diff --git a/lib/pry/commands/stat.rb b/lib/pry/commands/stat.rb index 84a3c47f..86c83cbd 100644 --- a/lib/pry/commands/stat.rb +++ b/lib/pry/commands/stat.rb @@ -16,10 +16,13 @@ class Pry def process meth = method_object + aliases = meth.aliases + output.puts unindent <<-EOS Method Information: -- Name: #{meth.name} + Alias#{ "es" if aliases.length > 1 }: #{ aliases.any? ? aliases.join(", ") : "None." } Owner: #{meth.owner ? meth.owner : "Unknown"} Visibility: #{meth.visibility} Type: #{meth.is_a?(::Method) ? "Bound" : "Unbound"} diff --git a/lib/pry/method.rb b/lib/pry/method.rb index 99eb086b..c3312e4c 100644 --- a/lib/pry/method.rb +++ b/lib/pry/method.rb @@ -403,6 +403,24 @@ class Pry source_file == Pry.eval_path end + # @return [Array] All known aliases for the method. + # @note On Ruby 1.8 this method always returns an empty Array for methods + # implemented in C. + def aliases + owner = @method.owner + # Avoid using `to_sym` on {Method#name}, which returns a `String`, because + # it won't be garbage collected. + name = @method.name + + alias_list = owner.instance_methods.combination(2).select do |pair| + owner.instance_method(pair.first) == owner.instance_method(pair.last) && + pair.include?(name) + end.flatten + alias_list.delete(name) + + alias_list.map(&:to_s) + end + # @return [Boolean] Is the method definitely an alias? def alias? name != original_name diff --git a/test/test_method.rb b/test/test_method.rb index dcf9258c..f4b895f8 100644 --- a/test/test_method.rb +++ b/test/test_method.rb @@ -1,4 +1,5 @@ require 'helper' +require 'set' describe Pry::Method do it "should use String names for compatibility" do @@ -397,5 +398,48 @@ describe Pry::Method do meth.send(:method_name_from_first_line, "def obj_name.x").should == "x" end end + + describe 'method aliases' do + before do + @class = Class.new { + def eat + end + + alias fress eat + alias_method :omnomnom, :fress + + def eruct + end + } + end + + it 'should be able to find method aliases' do + meth = Pry::Method(@class.new.method(:eat)) + aliases = Set.new(meth.aliases) + + aliases.should == Set.new(["fress", "omnomnom"]) + end + + it 'should return an empty Array if cannot find aliases' do + meth = Pry::Method(@class.new.method(:eruct)) + meth.aliases.should.be.empty + end + + it 'should not include the own name in the list of aliases' do + meth = Pry::Method(@class.new.method(:eat)) + meth.aliases.should.not.include "eat" + end + + unless Pry::Helpers::BaseHelpers.mri_18? + # Ruby 1.8 doesn't support this feature. + it 'should be able to find aliases for methods implemented in C' do + meth = Pry::Method(Hash.new.method(:key?)) + aliases = Set.new(meth.aliases) + + aliases.should == Set.new(["include?", "member?", "has_key?"]) + end + end + + end end