在Ruby中,类方法在接收器对象的单例类中查找。
class Child
class << self
def hello
p 'hello'
end
end
end
我明白这是如何运作的;它来自Child
的单身人士课程。
p Child.singleton_class.instance_methods(false)
>> [:hello]
但是当我们做这种情况下的继承时,
class Parent
class << self
def hello
p 'hello'
end
end
end
class Child < Parent
end
我不明白Child.hello
是如何运作的。类Child
不与其单例类链接,而是直接链接到Class
对象。
p Child.singleton_class.instance_methods(false)
>> []
然而,Parent
类与其单例类相关联,其中定义了hello
。
p Parent.singleton_class.instance_methods(false)
>>[:hello]
但我不明白调用Child.hello
如何查找Parent
的单例类中的方法。
这就是我看到连接对象的方式:
p Child.class.ancestors
>> [Class, Module, Object, Kernel, BasicObject]
答案 0 :(得分:2)
好的,既然这个问题被投了赞成票,我会在这里留下正确的答案。
double
的定义是因为Child.hello
的本征类派生自Child
的本征类:
Parent
这个本征类的整个祖先链将是:
▶ Child.singleton_class.superclass
#⇒ #<Class:Parent>
前四个祖先是▶ Child.singleton_class.ancestors
#⇒ [#<Class:Child>, #<Class:Parent>,
# #<Class:Object>, #<Class:BasicObject>,
# Class, Module, Object, Kernel, BasicObject]
链中各个类的特征类。这就是如何在ruby中构建/派生特征类,使Child.ancestors
之类的调用可用。
虽然Child.hello
方法没有直接显示:hello
方法,因为它不是在Child.singleton_class.instance_methods(false)
的本征类上定义的,它仍然存在,感谢Child
的eigenclass:
Parent
答案 1 :(得分:-3)
在调用Child.class.ancestors
之后,输出将显示类形式的祖先,其中Child是实例化的。是的,它可能看起来很奇怪而且令人困惑,但Child
是Class
类的实例。
如果你看一下在Ruby中声明类的另一种方式,它可能会变得更加清晰:
Child = Class.new { ... }
我猜这是你困惑的根源。你在错误的班级里寻找祖先。
如果你想看Child
的祖先:
Child.ancestors
=> [Parent, Object, Kernel, BasicObject]
or
Child.new.class.ancestors
=> [Parent, Object, Kernel, BasicObject]
我相信在指出之后,.hello
方法的查找对你来说变得清晰了。
答案 2 :(得分:-5)
Ruby不仅在单例类中查找方法。
以下是Ruby中继承和方法查找的入门知识:https://gist.github.com/damien-roche/351bf4e7991449714533