Ruby:无法理解为什么在class类中可以访问类方法

时间:2017-10-19 08:36:33

标签: ruby inheritance jruby

根据Ruby方法查找法,每当我们调用对象上的任何方法时,ruby就会使用公式object.class.ancestors找到该方法。如果这是真的,那么我不能使用Child类常量Child.parent来访问父类中定义的父方法,因为Child类的祖先是[Class, Module, Object, Kernel, BasicObject]。但我可以访问它。谁能告诉我为什么会这样?

class Parent
  def self.parent
    puts "i am parent"
  end
end

class Child < Parent
end

Child.parent # i am parent

enter image description here

my jruby version is jruby 1.7.16(1.9.3p392)2014-09-25 575b395 on Java HotSpot(TM)64-bit Server VM 1.8.0_20-b26 + jit [Windows 8.1-amd64]

2 个答案:

答案 0 :(得分:2)

您的理解并不完全正确。 object.class.ancestors没有为您提供搜索方法的类/模块的完整列表。这是一个反例:

foo = Object.new

def foo.bar
  puts "I'm inside the singleton class"
end

foo.class.ancestors # => [Object, Kernel, BasicObject]
foo.bar # "I'm inside the singleton class"

相反,你必须从对象的单例类开始:

foo.singleton_class.ancestors # => [#<Class:#<Object:0x007fa92c33c610>>, Object, Kernel, BasicObject]
foo.singleton_class.instance_methods.include?(:bar) # => true

知道在调用object.method_name时,#method_name会在

中的某处搜索
object.singleton_class.ancestors

并且Ruby类是常规对象,它仅代表Child.parent#parent将在

中查找
Child.singleton_class.ancestors

神奇的是,Ruby中的类方法在任何方面都不是特殊的。它们只是在类的单例类中定义。在您的示例中:

Child.singleton_class.ancestors # => [#<Class:Child>, #<Class:Parent>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]

如您所见,Child的单例类祖先链包含Parent的单例类。这就是为什么当您调用Child.parent时,实际上是在呼叫Parent.parent

答案 1 :(得分:1)

  

Child班级的家长是[Class, Module, Object, Kernel, BasicObject]

不,他们不是:

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

您可以访问Child.parent,因为Child继承自Parent

为了获得完整的图片,了解哪些方法可用于类的实例,您需要查看singleton_class

Child.singleton_class.ancestors
  #=> [#<Class:Child>, #<Class:Parent>, #<Class:Object>,
       #<Class:BasicObject>, Class, Module, Object,
       Kernel, BasicObject]