Ruby:无法理解为什么 class 方法可以在子 class 中访问
Ruby: Not able to understand why class method is accessible in child class
根据 Ruby 方法查找法则,只要我们在对象上调用任何方法,然后 ruby 就会使用公式 object.class.ancestors
找到该方法。如果这是真的,那么我不应该能够使用 Child
class 常量作为 Child.parent
访问父 class 中定义的父方法,因为 Child
class 是 [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
我的 jruby 版本是 jruby 1.7.16 (1.9.3p392) 2014-09-25 575b395 Java HotSpot(TM) 64 位服务器 VM 1.8 .0_20-b26 +jit [Windows 8.1-amd64]
the parents of Child
class are [Class, Module, Object, Kernel, BasicObject]
不,他们不是:
Child.ancestors
#=> [Child, Parent, Object, Kernel, BasicObject]
您可以访问 Child.parent
,因为 Child
继承自 Parent
。
但是,为了获得完整图片,了解哪些方法可用于 class 的实例,您需要查看 singleton_class
:
Child.singleton_class.ancestors
#=> [#<Class:Child>, #<Class:Parent>, #<Class:Object>,
#<Class:BasicObject>, Class, Module, Object,
Kernel, BasicObject]
您的理解并不完全正确。 object.class.ancestors
不会为您提供将在其中搜索方法的 classes/modules 的完整列表。这是一个反例:
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"
相反,您必须从对象的单例 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 class是常规对象,只代表Child.parent
,#parent
会在
的某处寻找
Child.singleton_class.ancestors
神奇的是 Ruby 中的 class 方法没有任何特殊之处。它们只是在 class 的单例 class 中定义的。在你的例子中:
Child.singleton_class.ancestors # => [#<Class:Child>, #<Class:Parent>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
如您所见,Child
的单例 class 祖先链包括 Parent
的单例 class。这就是为什么当你调用 Child.parent
时你实际上调用了 Parent.parent
.
根据 Ruby 方法查找法则,只要我们在对象上调用任何方法,然后 ruby 就会使用公式 object.class.ancestors
找到该方法。如果这是真的,那么我不应该能够使用 Child
class 常量作为 Child.parent
访问父 class 中定义的父方法,因为 Child
class 是 [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
我的 jruby 版本是 jruby 1.7.16 (1.9.3p392) 2014-09-25 575b395 Java HotSpot(TM) 64 位服务器 VM 1.8 .0_20-b26 +jit [Windows 8.1-amd64]
the parents of
Child
class are[Class, Module, Object, Kernel, BasicObject]
不,他们不是:
Child.ancestors
#=> [Child, Parent, Object, Kernel, BasicObject]
您可以访问 Child.parent
,因为 Child
继承自 Parent
。
但是,为了获得完整图片,了解哪些方法可用于 class 的实例,您需要查看 singleton_class
:
Child.singleton_class.ancestors
#=> [#<Class:Child>, #<Class:Parent>, #<Class:Object>,
#<Class:BasicObject>, Class, Module, Object,
Kernel, BasicObject]
您的理解并不完全正确。 object.class.ancestors
不会为您提供将在其中搜索方法的 classes/modules 的完整列表。这是一个反例:
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"
相反,您必须从对象的单例 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 class是常规对象,只代表Child.parent
,#parent
会在
Child.singleton_class.ancestors
神奇的是 Ruby 中的 class 方法没有任何特殊之处。它们只是在 class 的单例 class 中定义的。在你的例子中:
Child.singleton_class.ancestors # => [#<Class:Child>, #<Class:Parent>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
如您所见,Child
的单例 class 祖先链包括 Parent
的单例 class。这就是为什么当你调用 Child.parent
时你实际上调用了 Parent.parent
.