Handle evil classes that define 'ancestors'

This commit is contained in:
☈king 2013-02-26 07:28:37 -06:00 committed by rking@sharpsaw.org
parent 552b7e18e5
commit aea6836530
5 changed files with 19 additions and 6 deletions

View File

@ -28,7 +28,8 @@ class Pry
unless String === stringified
# Read the class name off of the singleton class to provide a default
# inspect.
klass = (class << value; self; end).ancestors.first
eig = class << value; self; end
klass = Pry::Method.safe_send(eig, :ancestors).first
id = value.__id__.to_s(16) rescue 0
stringified = "#<#{klass}:0x#{id}>"
end

View File

@ -154,7 +154,13 @@ class Pry
# traversal of the Object's ancestry graph.
def below_ceiling(obj)
ceiling = if opts.present?(:quiet)
[opts.present?(:'instance-methods') ? obj.ancestors[1] : obj.class.ancestors[1]] + Pry.config.ls.ceiling
[
if opts.present?(:'instance-methods')
Pry::Method.safe_send(obj, :ancestors)[1]
else
Pry::Method.safe_send(obj.class, :ancestors)[1]
end
] + Pry.config.ls.ceiling
elsif opts.present?(:verbose)
[]
else

View File

@ -170,7 +170,7 @@ class Pry
# @return [Array[Class, Module]]
def instance_resolution_order(klass)
# include klass in case it is a singleton class,
([klass] + klass.ancestors).uniq
([klass] + Pry::Method.safe_send(klass, :ancestors)).uniq
end
def method_definition?(name, definition_line)
@ -206,7 +206,7 @@ class Pry
# If a module is included at multiple points in the ancestry, only
# the lowest copy will be returned.
def singleton_class_resolution_order(klass)
resolution_order = klass.ancestors.map do |anc|
resolution_order = Pry::Method.safe_send(klass, :ancestors).map do |anc|
[singleton_class(anc)] + singleton_class(anc).included_modules if anc.is_a?(Class)
end.compact.flatten(1)

View File

@ -80,7 +80,8 @@ class Pry
if method.arity == 0
consts = method.call
if !inherit
consts -= (@wrapped.ancestors - [@wrapped]).map(&:constants).flatten
ancestors_ = Pry::Method.safe_send(@wrapped, :ancestors)
consts -= (ancestors_ - [@wrapped]).map(&:constants).flatten
end
else
consts = method.call(inherit)
@ -120,7 +121,7 @@ class Pry
# Is this a singleton class?
# @return [Boolean]
def singleton_class?
wrapped != wrapped.ancestors.first
wrapped != Pry::Method.safe_send(wrapped, :ancestors).first
end
# Is this strictly a module? (does not match classes)

View File

@ -59,6 +59,11 @@ describe "ls" do
# This doesn't actually touch the network, promise!
pry_eval("ls Net::HTTP::Get.new('localhost')").should =~ /Net::HTTPGenericRequest#methods/
end
it "should handle classes that (pathologically) define .ancestors" do
output = pry_eval("ls Class.new{ def self.ancestors; end; def hihi; end }")
output.should =~ /hihi/
end
end
describe 'with -l' do