diff --git a/lib/pry/commands/show_info.rb b/lib/pry/commands/show_info.rb index 2789ba0e..1c1ba346 100644 --- a/lib/pry/commands/show_info.rb +++ b/lib/pry/commands/show_info.rb @@ -19,24 +19,40 @@ class Pry def process code_object = Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super]) - raise Pry::CommandError, "Couldn't locate #{obj_name}!" if !code_object + cannot_locate_source_error if !code_object if show_all_modules?(code_object) # show all monkey patches for a module - @all_modules = true result = content_and_headers_for_all_module_candidates(code_object) else # show a specific code object - @all_modules = false - result = content_and_header_for_code_object(code_object) + co = code_object_with_accessible_source(code_object) + result = content_and_header_for_code_object(co) end set_file_and_dir_locals(code_object.source_file) stagger_output result end + # This method checks whether the `code_object` is a WrappedModule, + # if it is, then it returns the first candidate (monkeypatch) with + # accessible source (or docs). If `code_object` is not a WrappedModule (i.e a + # method or a command) then the `code_object` itself is just + # returned. + # + # @return [Pry::WrappedModule, Pry::Method, Pry::Command] + def code_object_with_accessible_source(code_object) + if code_object.is_a?(WrappedModule) + code_object.candidates.find(&:source).tap do |candidate| + cannot_locate_source_error if !candidate + end + else + code_object + end + end + def content_and_header_for_code_object(code_object) header(code_object) + content_for(code_object) end @@ -58,6 +74,10 @@ class Pry result end + def cannot_locate_source_error + raise CommandError, "Couldn't locate a definition for #{obj_name}!" + end + # Generate a header (meta-data information) for all the code # object types: methods, modules, commands, procs... def header(code_object) @@ -124,10 +144,6 @@ class Pry end end - def all_modules? - @all_modules - end - def complete(input) if input =~ /([^ ]*)#([a-z0-9_]*)\z/ prefix, search = [$1, $2] diff --git a/lib/pry/commands/show_source.rb b/lib/pry/commands/show_source.rb index 73356d2e..e5477658 100644 --- a/lib/pry/commands/show_source.rb +++ b/lib/pry/commands/show_source.rb @@ -25,6 +25,8 @@ class Pry # The source for code_object prepared for display. def content_for(code_object) + cannot_locate_source_error if !code_object.source + Code.new(code_object.source, start_line_for(code_object)). with_line_numbers(use_line_numbers?).to_s end diff --git a/spec/commands/show_doc_spec.rb b/spec/commands/show_doc_spec.rb index 3af29340..06441e74 100644 --- a/spec/commands/show_doc_spec.rb +++ b/spec/commands/show_doc_spec.rb @@ -279,34 +279,34 @@ if !PryTestHelpers.mri18_and_no_real_source_location? # FIXME: THis is nto a good spec anyway, because i dont think it # SHOULD skip! - # describe "should skip over broken modules" do - # before do - # module TestHost - # # hello - # module M - # binding.eval("def a; end", "dummy.rb", 1) - # binding.eval("def b; end", "dummy.rb", 2) - # binding.eval("def c; end", "dummy.rb", 3) - # end + describe "should skip over broken modules" do + before do + module TestHost + # hello + module M + binding.eval("def a; end", "dummy.rb", 1) + binding.eval("def b; end", "dummy.rb", 2) + binding.eval("def c; end", "dummy.rb", 3) + end - # # goodbye - # module M - # def d; end - # def e; end - # end - # end - # end + # goodbye + module M + def d; end + def e; end + end + end + end - # after do - # Object.remove_const(:TestHost) - # end + after do + Object.remove_const(:TestHost) + end - # it 'should return doc for first valid module' do - # result = pry_eval("show-doc TestHost::M") - # result.should =~ /goodbye/ - # result.should.not =~ /hello/ - # end - # end + it 'should return doc for first valid module' do + result = pry_eval("show-doc TestHost::M") + result.should =~ /goodbye/ + result.should.not =~ /hello/ + end + end end describe "on commands" do diff --git a/spec/commands/show_source_spec.rb b/spec/commands/show_source_spec.rb index 57ab9fea..8326ef1d 100644 --- a/spec/commands/show_source_spec.rb +++ b/spec/commands/show_source_spec.rb @@ -491,7 +491,7 @@ if !PryTestHelpers.mri18_and_no_real_source_location? proc { pry_eval(TestHost::C, 'show-source') }.should.raise(Pry::CommandError). - message.should =~ /Cannot find a definition for/ + message.should =~ /Couldn't locate/ end it 'should display method code (rather than class) if Pry started inside method binding' do @@ -535,14 +535,11 @@ if !PryTestHelpers.mri18_and_no_real_source_location? Object.remove_const(:BabyDuck) end - # TODO: !!! This is a bad spec, should not be expected behaviour?!?! - # - # it 'should return source for first valid module' do - # out = pry_eval('show-source BabyDuck::Muesli') - # out.should =~ /def d; end/ - # out.should.not =~ /def a; end/ - # end - + it 'should return source for first valid module' do + out = pry_eval('show-source BabyDuck::Muesli') + out.should =~ /def d; end/ + out.should.not =~ /def a; end/ + end end end end