Object如何知道const_get方法?

mbi*_*ras 4 ruby

我正在阅读另一个问题,其答案提到使用Module#const_get实例方法在模块中查找类.例如:

module M
  class C
  end
end

p M.const_get 'C'
#=> M::C
Run Code Online (Sandbox Code Playgroud)

我很好奇这个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'
...
Run Code Online (Sandbox Code Playgroud)

这似乎Object::const_get是一种单身方法.在我们的上下文中使用它:

module M
  class C
  end
end

p Object.const_get 'M::C'
#=> M::C
Run Code Online (Sandbox Code Playgroud)

但是没有关于该单例方法的文档记录:

ri Object::const_get
Nothing known about Object::const_get
ri Object.const_get
Nothing known about Object.const_get
Run Code Online (Sandbox Code Playgroud)

这让我感到困惑,因为我知道一个Module是一个ObjectObject不是一个Module:

Module.ancestors
#=> [Module, Object, Kernel, BasicObject]
Object.ancestors
#=> [Object, Kernel, BasicObject]
Run Code Online (Sandbox Code Playgroud)

除此之外我使用Object#is_a?实例方法检查并发现我错了:

Module.is_a? Object
#=> true
Object.is_a? Module
#=> true
Run Code Online (Sandbox Code Playgroud)

最初是一个无辜的ri查询导致我对整个Ruby对象模型感到困惑.

  • 为什么Object.is_a? Module #=> true如果ModuleObject始祖链?
  • 怎么Object知道这个const_get方法?

tad*_*man 6

这是一个对象的类和对象的单例类之间不明白分离的工件,这是一类每个类用​​于此类事物的影子类.

您可以使用以下singleton_class方法在Ruby 2.5+中轻松访问它:

Object.singleton_class.ancestors
# => [#<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
Run Code Online (Sandbox Code Playgroud)

哪里Module出现在这里,所以这些方法混合在一起并可以通过调用Object.

对象本身具有相对枯燥的继承链:

Object.ancestors
#=> [Object, Kernel, BasicObject]
Run Code Online (Sandbox Code Playgroud)

Ruby中的每个对象都有一个类,即使Class是一个类Object,它也有一个关联的类Class.