我正在使用another question阅读answer,提到使用Module#const_get
实例方法在模块中查找类。例如:
module M
class C
end
end
p M.const_get 'C'
#=> M::C
我对const_get
方法感到好奇,因此我使用了ri
并找到了:
ri Module#const_get
...
This method will recursively look up constant names if a namespaced
class name is provided. For example:
module Foo; class Bar; end end
Object.const_get 'Foo::Bar'
...
似乎Object::const_get
是单身方法。在我们的上下文中使用它:
module M
class C
end
end
p Object.const_get 'M::C'
#=> M::C
但是没有关于该单例方法的任何记录:
ri Object::const_get
Nothing known about Object::const_get
ri Object.const_get
Nothing known about Object.const_get
这使我感到困惑,因为我知道Module
是Object
但Object
不是Module
:
Module.ancestors
#=> [Module, Object, Kernel, BasicObject]
Object.ancestors
#=> [Object, Kernel, BasicObject]
除此之外,我使用Object#is_a?
实例方法检查并发现我错了:
Module.is_a? Object
#=> true
Object.is_a? Module
#=> true
最初的无辜ri
查询导致我对整个Ruby对象模型感到困惑。
Object.is_a? Module #=> true
Module
不在Object
的祖先链中,为什么Object
?const_get
如何了解gh-pages
方法?答案 0 :(得分:5)
这是一个对象类和对象的单例类之间不明白分离的工件,这是一种影子类,每个类都用于这样的事情。
您可以使用singleton_class
方法在Ruby 2.5+中轻松访问它:
Object.singleton_class.ancestors
# => [#<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
Module
在这里出现的地方,这就是这些方法混合的方式,可以通过Object
调用。
对象本身具有相对枯燥的继承链:
Object.ancestors
#=> [Object, Kernel, BasicObject]
Ruby中的每个对象都有一个类,即使Class
也是Object
,它也有一个关联的Class
。
答案 1 :(得分:1)
我认为你的困惑源于同时从两个方向看Object
:
Object
是一个类,因此Object.ancestors
可用于查看继承层次结构。这告诉您Object < Kernel
为真,Object < Module
为假。Class
类的实例。这会以与Object.is_a? Class
相同的方式告诉您Object.is_a? Module
和'pancakes'.is_a? String
。而Object.const_get
方法调用的方式与'pancakes'.upcase
方法调用的方式相同。您可以将some_obj.is_a? SomeClass
视为一种较短的说法some_obj.class.ancestors.include? SomeClass
。
回答您的具体问题:
Object.is_a? Module #=> true
为什么Module
不在Object
的祖先链中?
因为is_a?
和ancestors
正在考虑不同的事情。
Object
如何了解const_get
方法?
因为Object
是Class
类的实例,而Class
在其祖先中包含Module
。与'pancakes'
类的实例类似,String
类在其祖先中具有Kernel
,因此'pancakes'
具有object_id
方法。
答案 2 :(得分:0)
Object.is_a? Module #=> true
is_a?
询问Object
是Module
的实例(或专门实例)。 Class
是Module
的子类,因此Class
的所有实例都只是Module
的专用实例。由于Object
是Class
的一个实例,因此Object
也是Module
的一个实例。
Module#const_get
const_get
是Module
类中定义的实例方法。由于Object
是Module
的一个实例(由于上述原因),因此可以访问Module#const_get
。