根据Ruby方法查找法,每当我们调用对象上的任何方法时,ruby就会使用公式object.class.ancestors
找到该方法。如果这是真的,那么我不能使用Child
类常量Child.parent
来访问父类中定义的父方法,因为Child
类的祖先是[Class, Module, Object, Kernel, BasicObject]
。但我可以访问它。谁能告诉我为什么会这样?
class Parent
def self.parent
puts "i am parent"
end
end
class Child < Parent
end
Child.parent # i am parent
my jruby version is jruby 1.7.16(1.9.3p392)2014-09-25 575b395 on Java HotSpot(TM)64-bit Server VM 1.8.0_20-b26 + jit [Windows 8.1-amd64]
答案 0 :(得分:2)
您的理解并不完全正确。 object.class.ancestors
没有为您提供搜索方法的类/模块的完整列表。这是一个反例:
foo = Object.new
def foo.bar
puts "I'm inside the singleton class"
end
foo.class.ancestors # => [Object, Kernel, BasicObject]
foo.bar # "I'm inside the singleton class"
相反,你必须从对象的单例类开始:
foo.singleton_class.ancestors # => [#<Class:#<Object:0x007fa92c33c610>>, Object, Kernel, BasicObject]
foo.singleton_class.instance_methods.include?(:bar) # => true
知道在调用object.method_name
时,#method_name
会在
object.singleton_class.ancestors
并且Ruby类是常规对象,它仅代表Child.parent
,#parent
将在
Child.singleton_class.ancestors
神奇的是,Ruby中的类方法在任何方面都不是特殊的。它们只是在类的单例类中定义。在您的示例中:
Child.singleton_class.ancestors # => [#<Class:Child>, #<Class:Parent>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
如您所见,Child
的单例类祖先链包含Parent
的单例类。这就是为什么当您调用Child.parent
时,实际上是在呼叫Parent.parent
。
答案 1 :(得分:1)
Child
班级的家长是[Class, Module, Object, Kernel, BasicObject]
不,他们不是:
Child.ancestors
#=> [Child, Parent, Object, Kernel, BasicObject]
您可以访问Child.parent
,因为Child
继承自Parent
。
为了获得完整的图片,了解哪些方法可用于类的实例,您需要查看singleton_class
:
Child.singleton_class.ancestors
#=> [#<Class:Child>, #<Class:Parent>, #<Class:Object>,
#<Class:BasicObject>, Class, Module, Object,
Kernel, BasicObject]