在ruby中继承期间类方法查找是如何工作的?

在ruby中继承期间类方法查找是如何工作的?,ruby,Ruby,在Ruby中,在receiver对象的singleton类中查找类方法 class Child class << self def hello p 'hello' end end end 但是当我们做继承的时候,比如在这种情况下 class Parent class << self def hello p 'hello' end end end class Child < Parent en

在Ruby中,在receiver对象的singleton类中查找类方法

class Child
  class << self
    def hello
      p 'hello'
    end
  end
end
但是当我们做继承的时候,比如在这种情况下

class Parent
  class << self
    def hello
      p 'hello'
    end
  end
end

class Child < Parent
end
然而,
Parent
类链接到它的singleton类,其中定义了
hello

p Parent.singleton_class.instance_methods(false)
>>[:hello]
但是我不明白调用
Child.hello
如何在
Parent
的singleton类中查找该方法

这是我如何看到连接的对象的:

p Child.class.ancestors   
>> [Class, Module, Object, Kernel, BasicObject]

Ruby不仅仅是在singleton类中查找方法

p Child.singleton_class.instance_methods(false)
>> [:hello]

以下是Ruby中继承和方法查找的入门知识:

在调用
Child.class.祖先
之后,输出将显示实例化子类的类形式的祖先。是的,它可能看起来很奇怪和混乱,但是
Child
Class
Class的一个实例

如果您看看用Ruby声明类的另一种方法,它可能会变得更清晰:

Child = Class.new { ... }
我想这就是你困惑的根源。你在找错门类的祖先

如果要查看孩子的祖先,请执行以下操作:

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

or

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

我相信在指出这一点之后,查找
.hello
方法对您来说就变得很清楚了。

好的,既然这个问题被否决了,我将在这里留下正确的答案

Child.hello
之所以被定义,是因为
Child
的本征类是从
Parent
的本征类派生而来的:

▶ Child.singleton_class.superclass
#⇒ #<Class:Parent>
▶ Child.singleton_class.instance_methods.detect &:hello.method(:==)
#⇒ :hello

Child.singleton\u class.superclass#=>#
您是否意识到
instance\u方法(false)
意味着没有正确地包含继承的方法?它正在singleton类中查找方法。你发布的链接也说了同样的事情。如果你仔细阅读我的答案,你会发现我写了“Ruby不仅仅是在singleton类中查找方法”。啊!很抱歉仅遗漏:因此不欢迎PPure链接。这可能是一个很好的评论,但无论如何都不是答案。老实说,除非我读过上面的内容,否则我对
.hello
方法的查找是非常清楚的。现在我很困惑:)
孩子。祖先与
毫无关系。你好<代码>子类.单类.祖先类
do。祖先的链对于类的实例的查找方法是有效的,例如<代码>子< /代码>,但不适用于类<代码>子< /代码>。@ YAKE注意到您在发布的链中调用<代码>类< /代码>的方法调用,然后考虑您的注释。虽然我不喜欢这个答案,但你的评论更是大错特错。能解释一下它是怎么错的吗?本征类添加到对象链中,但未通过
祖先
方法显示。这可能会让人困惑,但并没有错。
▶ Child.singleton_class.ancestors
#⇒ [#<Class:Child>, #<Class:Parent>, 
#   #<Class:Object>, #<Class:BasicObject>,
#   Class, Module, Object, Kernel, BasicObject]
▶ Child.singleton_class.instance_methods.detect &:hello.method(:==)
#⇒ :hello