1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

show class/module body when show-source invoked with no args

This commit is contained in:
John Mair 2012-06-28 15:32:45 +12:00
parent a58457fdae
commit e7f72d804c
3 changed files with 86 additions and 3 deletions

View file

@ -20,13 +20,26 @@ class Pry
def process(name)
if module?(name)
code_or_doc = process_module
else method?
elsif method?
code_or_doc = process_method
else
code_or_doc = process_alternatives
end
render_output(code_or_doc, opts)
end
def process_alternatives
if args.empty? && internal_binding?(target)
mod = target_self.is_a?(Module) ? target_self : target_self.class
self.module_object = Pry::WrappedModule(mod)
process_module
else
process_method
end
end
def module_start_line(mod, candidate_rank=0)
if opts.present?(:'base-one')
1

View file

@ -39,13 +39,16 @@ class Pry
[file, line_num]
end
def internal_binding?(target)
m = target.eval("__method__").to_s
["__binding__", "__binding_impl__"].include?(m)
end
def get_method_or_raise(name, target, opts={}, omit_help=false)
meth = Pry::Method.from_str(name, target, opts)
if name && !meth
command_error("The method '#{name}' could not be found.", omit_help)
elsif !meth
command_error("No method name given, and context is not a method.", omit_help, NonMethodContextError)
end
(opts[:super] || 0).times do
@ -56,6 +59,10 @@ class Pry
end
end
if !meth || (!name && internal_binding?(target))
command_error("No method name given, and context is not a method.", omit_help, NonMethodContextError)
end
set_file_and_dir_locals(meth.source_file)
meth
end

View file

@ -321,6 +321,69 @@ if !mri18_and_no_real_source_location?
result.should =~ /def instance_eval_method/
end
end
describe "when show-source is invoked without a method or class argument" do
before do
module Host
module M
def alpha; end
def beta; end
end
module C
end
module D
def self.invoked_in_method
redirect_pry_io(InputTester.new("show-source", "exit-all"), out = StringIO.new) do
Pry.start(binding)
end
out.string
end
end
end
end
after do
Object.remove_const(:Host)
end
describe "inside a module" do
it 'should display module source by default' do
redirect_pry_io(InputTester.new("show-source", "exit-all"), out = StringIO.new) do
Pry.start(Host::M)
end
out.string.should =~ /module M/
out.string.should =~ /def alpha/
out.string.should =~ /def beta/
end
it 'should be unable to find module source if no methods defined' do
redirect_pry_io(InputTester.new("show-source", "exit-all"), out = StringIO.new) do
Pry.start(Host::C)
end
out.string.should.should =~ /Cannot find a definition for/
end
it 'should display method code (rather than class) if Pry started inside method binding' do
string = Host::D.invoked_in_method
string.should =~ /invoked_in_method/
string.should.not =~ /module D/
end
it 'should allow options to be passed' do
redirect_pry_io(InputTester.new("show-source -b", "exit-all"), out = StringIO.new) do
Pry.start(Host::M)
end
out.string.should =~ /\d:\s*module M/
out.string.should =~ /\d:\s*def alpha/
out.string.should =~ /\d:\s*def beta/
end
end
end
end
end
end