Ruby:无法理解为什么 class 方法可以在子 class 中访问

Ruby: Not able to understand why class method is accessible in child class

根据 Ruby 方法查找法则,只要我们在对象上调用任何方法,然后 ruby 就会使用公式 object.class.ancestors 找到该方法。如果这是真的,那么我不应该能够使用 Child class 常量作为 Child.parent 访问父 class 中定义的父方法,因为 Child class 是 [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

我的 jruby 版本是 jruby 1.7.16 (1.9.3p392) 2014-09-25 575b395 Java HotSpot(TM) 64 位服务器 VM 1.8 .0_20-b26 +jit [Windows 8.1-amd64]

the parents of Child class are [Class, Module, Object, Kernel, BasicObject]

不,他们不是:

Child.ancestors
 #=> [Child, Parent, Object, Kernel, BasicObject]

您可以访问 Child.parent,因为 Child 继承自 Parent

但是,为了获得完整图片,了解哪些方法可用于 class 的实例,您需要查看 singleton_class :

Child.singleton_class.ancestors
  #=> [#<Class:Child>, #<Class:Parent>, #<Class:Object>,
       #<Class:BasicObject>, Class, Module, Object,
       Kernel, BasicObject]

您的理解并不完全正确。 object.class.ancestors 不会为您提供将在其中搜索方法的 classes/modules 的完整列表。这是一个反例:

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"

相反,您必须从对象的单例 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 class是常规对象,只代表Child.parent#parent会在

的某处寻找
Child.singleton_class.ancestors

神奇的是 Ruby 中的 class 方法没有任何特殊之处。它们只是在 class 的单例 class 中定义的。在你的例子中:

Child.singleton_class.ancestors # => [#<Class:Child>, #<Class:Parent>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]

如您所见,Child 的单例 class 祖先链包括 Parent 的单例 class。这就是为什么当你调用 Child.parent 时你实际上调用了 Parent.parent.