Object如何知道const_get方法?

时间:2018-04-16 22:35:09

标签: ruby

我正在使用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

这使我感到困惑,因为我知道ModuleObjectObject不是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方法?

3 个答案:

答案 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

  1. Object是一个类,因此Object.ancestors可用于查看继承层次结构。这告诉您Object < Kernel为真,Object < Module为假。
  2. Ruby中的类也是对象,特别是它们是Class类的实例。这会以与Object.is_a? Class相同的方式告诉您Object.is_a? Module'pancakes'.is_a? String。而Object.const_get方法调用的方式与'pancakes'.upcase方法调用的方式相同。
  3. 您可以将some_obj.is_a? SomeClass视为一种较短的说法some_obj.class.ancestors.include? SomeClass

    回答您的具体问题:

    1.   

      Object.is_a? Module #=> true为什么Module不在Object的祖先链中?

      因为is_a?ancestors正在考虑不同的事情。

    2.   

      Object如何了解const_get方法?

      因为ObjectClass类的实例,而Class在其祖先中包含Module。与'pancakes'类的实例类似,String类在其祖先中具有Kernel,因此'pancakes'具有object_id方法。

答案 2 :(得分:0)

Object.is_a? Module #=> true

is_a?询问ObjectModule的实例(或专门实例)。 ClassModule的子类,因此Class的所有实例都只是Module的专用实例。由于ObjectClass的一个实例,因此Object也是Module的一个实例。

Module#const_get

const_getModule类中定义的实例方法。由于ObjectModule的一个实例(由于上述原因),因此可以访问Module#const_get