From bb23c4bb31276cef893a7fececf37005b6589db0 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Sun, 7 Apr 2013 13:24:28 -0700 Subject: [PATCH] Find nested module definitions [Fixes #832] This fixes `$ ActionController::ForceSSL` --- lib/pry/wrapped_module.rb | 19 ++++++++++++++++++- spec/wrapped_module_spec.rb | 20 +++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/lib/pry/wrapped_module.rb b/lib/pry/wrapped_module.rb index cdd3e34e..d9612758 100644 --- a/lib/pry/wrapped_module.rb +++ b/lib/pry/wrapped_module.rb @@ -348,7 +348,17 @@ class Pry # given module. # @return [Array] def all_methods_for(mod) - all_from_common(mod, :instance_method) + all_from_common(mod, :method) + methods = all_from_common(mod, :instance_method) + all_from_common(mod, :method) + + return methods unless methods.empty? + + safe_send(mod, :constants).map do |const_name| + if const = nested_module?(mod, const_name) + all_methods_for(const) + else + [] + end + end.flatten end # FIXME: a variant of this method is also found in Pry::Method @@ -366,6 +376,13 @@ class Pry end.flatten end + def nested_module?(parent, name) + child = safe_send(parent, :const_get, name) + return unless Module === child + return unless safe_send(child, :name) == "#{safe_send(parent, :name)}::#{name}" + child + end + # Detect methods that are defined with `def_delegator` from the Forwardable # module. We want to reject these methods as they screw up module # extraction since the `source_location` for such methods points at forwardable.rb diff --git a/spec/wrapped_module_spec.rb b/spec/wrapped_module_spec.rb index 0771333c..7ed41f5b 100644 --- a/spec/wrapped_module_spec.rb +++ b/spec/wrapped_module_spec.rb @@ -22,6 +22,11 @@ describe Pry::WrappedModule do end end + class PitifullyBlank + DEFAULT_TEST = CandidateTest + end + + FOREVER_ALONE_LINE = __LINE__ + 1 class ForeverAlone class DoublyNested # nested docs @@ -39,8 +44,12 @@ describe Pry::WrappedModule do Pry::WrappedModule(Host::CandidateTest).number_of_candidates.should == 3 end - it 'should return 0 candidates for a class with no methods and no other definitions' do - Pry::WrappedModule(Host::ForeverAlone).number_of_candidates.should == 0 + it 'should return 0 candidates for a class with no nested modules or methods' do + Pry::WrappedModule(Host::PitifullyBlank).number_of_candidates.should == 0 + end + + it 'should return 1 candidate for a class with a nested module with methods' do + Pry::WrappedModule(Host::ForeverAlone).number_of_candidates.should == 1 end end @@ -68,8 +77,13 @@ describe Pry::WrappedModule do wm.source_location.should == wm.candidate(0).source_location end + it 'should return the location of the outer module if an inner module has methods' do + wm = Pry::WrappedModule(Host::ForeverAlone) + wm.source_location.should == [__FILE__, Host::FOREVER_ALONE_LINE] + end + it 'should return nil if no source_location can be found' do - Pry::WrappedModule(Host::ForeverAlone).source_location.should == nil + Pry::WrappedModule(Host::PitifullyBlank).source_location.should == nil end end