diff --git a/lib/pry/helpers/command_helpers.rb b/lib/pry/helpers/command_helpers.rb index 11faf4cd..7a8fc937 100644 --- a/lib/pry/helpers/command_helpers.rb +++ b/lib/pry/helpers/command_helpers.rb @@ -29,14 +29,24 @@ class Pry end def get_method_or_raise(name, target, opts={}, omit_help=false) - if (meth = Pry::Method.from_str(name, target, opts)) - set_file_and_dir_locals(meth.source_file) - meth - elsif name + meth = Pry::Method.from_str(name, target, opts) + + if name && !meth command_error("The method '#{name}' could not be found.", omit_help) - else + elsif !meth command_error("No method name given, and context is not a method.", omit_help) end + + (opts[:super] || 0).times do + if meth.super + meth = meth.super + else + command_error("The method '#{meth.name}' is not defined in a superclass of '#{class_name(meth.owner)}'.", omit_help) + end + end + + set_file_and_dir_locals(meth.source_file) + meth end def command_error(message, omit_help) diff --git a/lib/pry/helpers/options_helpers.rb b/lib/pry/helpers/options_helpers.rb index 05bbedb8..acd72f3f 100644 --- a/lib/pry/helpers/options_helpers.rb +++ b/lib/pry/helpers/options_helpers.rb @@ -34,6 +34,7 @@ class Pry @method_target = target opt.on :M, "instance-methods", "Operate on instance methods." opt.on :m, :methods, "Operate on methods." + opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors." opt.on :c, :context, "Select object context to run under.", true do |context| @method_target = Pry.binding_for(target.eval(context)) end @@ -42,6 +43,8 @@ class Pry # Add the derived :method_object option to a used Slop instance. def process_method_object_options(args, opts) opts[:instance] = opts['instance-methods'] if opts.m? + # TODO: de-hack when we upgrade Slop: https://github.com/injekt/slop/pull/30 + opts.options[:super].force_argument_value opts.options[:super].count if opts.super? method_obj = get_method_or_raise(args.empty? ? nil : args.join(" "), @method_target, opts.to_hash(true)) opts.on(:method_object, :default => method_obj) end diff --git a/test/helper.rb b/test/helper.rb index 1cf7ee1a..7bd60db9 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -94,11 +94,14 @@ def redirect_pry_io(new_in, new_out = StringIO.new) end def mock_pry(*args) + + binding = args.first.is_a?(Binding) ? args.shift : binding() + input = InputTester.new(*args) output = StringIO.new redirect_pry_io(input, output) do - Pry.start + binding.pry end output.string diff --git a/test/test_default_commands/test_documentation.rb b/test/test_default_commands/test_documentation.rb index 235c29b9..80a1ca12 100644 --- a/test/test_default_commands/test_documentation.rb +++ b/test/test_default_commands/test_documentation.rb @@ -27,5 +27,28 @@ describe "Pry::DefaultCommands::Documentation" do $str_output.string.should =~ /sample comment/ $str_output = nil end + + it "should be able to find super methods" do + + c = Class.new{ + # classy initialize! + def initialize(*args); end + } + + d = Class.new(c){ + # grungy initialize?? + def initialize(*args, &block); end + } + + o = d.new + + # instancey initialize! + def o.initialize; end + + mock_pry(binding, "show-doc o.initialize").should =~ /instancey initialize/ + mock_pry(binding, "show-doc --super o.initialize").should =~ /grungy initialize/ + mock_pry(binding, "show-doc o.initialize -ss").should =~ /classy initialize/ + mock_pry(binding, "show-doc --super o.initialize -ss").should == mock_pry("show-doc Object#initialize") + end end end