为什么singleton方法(又名:类方法)继承



我对这种行为有些惊讶:

puts RUBY_VERSION # 2.4.1
class A
  class << A
    def my_method
      puts self
    end
  end
end
class B < A ; end
puts A.singleton_methods.inspect # [:my_method]
puts B.singleton_methods.inspect # [:my_method]
puts B.my_method # B
puts A.my_method # A

在元编程Ruby 2(Amazing Book BTW(中,Paolo Perrota说:

另外,单身人士只有一个实例(这是他们的名字来自的地方(,并且无法继承

,但是我们可以看到,nipet中的类方法已由B中的B继承。因此,有人可以向我解释它是如何工作的吗?

这种行为是否意味着课程是Singleton类的实例?

(老实说,我在重新解释了本书的一部分之前写了这本书,以解释班级方法的继承机制。但是现在我了解它仍然认为是一个有趣的话题(

为什么要继承类方法?

  1. 每个班级都有Singleton班级,
  2. 当有继承Hierachy时,Singleton类继承链反映了其中之一"正常"词组。
  3. 在Ruby方法查找过程中,解释器通过Singleton类的继承链。
puts RUBY_VERSION # 2.4.1
class A
  class << A
    def my_method
      puts self
    end
  end
end
class B < A ; end
puts A.singleton_class == B.singleton_class.superclass # true
puts A == B.superclass # true

因此,在方法查找过程中,解释器上升到B的Singleton类,寻找方法my_method在那里找不到它,然后转到A的Singleton类,并在那里找到方法和执行它。

,但我们应该承认,在竞争中,他们有两个阶级的继承链,因为这两个链条必须首先穿越。但是哪一个?

好吧,如果您知道的话,请告诉我,但是代码似乎在说话:

puts RUBY_VERSION # 2.4.1
class Class
  def my_method
    puts "Those who seek for gold dig up much earth and find a little."
  end
end
A = Class.new do
  class << self
    def my_method
      puts self
    end
  end
end
class B < A ; end
Class.new.my_method # Those who seek for gold dig up much earth and find a little.
A.my_method # A

如果"常规"继承链将优先于单尔顿类的继承链,则A.my_method的结果在Class.new.my_method中是相同的,因为A的类是Class。如果我们删除了A的Singleton方法,我们可以更清楚地看到它:

puts RUBY_VERSION # 2.4.1
class Class
  def my_method
    puts "Those who seek for gold dig up much earth and find a little."
  end
end
A = Class.new do
  # class << self
  #   def my_method
  #     puts self
  #   end
  # end
end
class B < A ; end
Class.new.my_method # Those who seek for gold dig up much earth and find a little.
A.my_method # Those who seek for gold dig up much earth and find a little.

这些行为意味着课程是Singleton类的实例?

我真的很想回答这个问题。但是我不太确定。这是否意味着例如A既是Class的实例,又是它自己的单例类?双继承!?

如果您了解得更好,请分享您的知识。这是一个非常有趣的话题:(

最新更新