gpt4 book ai didi

ruby - 为什么单例方法(AKA : class methods) are inherited?

转载 作者:数据小太阳 更新时间:2023-10-29 08:56:24 24 4
gpt4 key购买 nike

我对这种行为有点惊讶:

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(神奇的书顺便说一句)中,Paolo Perrota 说:

此外,单例类只有一个实例(这就是它们名字的由来),它们不能被继承

但是我们可以看到代码片段中的类方法已经被B继承自A。所以,谁能解释一下它是如何工作的?

这种行为是否意味着类是单例类的实例?

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

最佳答案

为什么要继承类方法?

  1. 每个类都有单例类,
  2. 当存在继承层次结构时,单例类继承链反射(reflect)了其中的一个“正常”类(class)。
  3. 在Ruby方法查找过程中,解释器遍历单例类的继承链。
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 的单例类,查找方法 my_method 在那里找不到,然后上到 A 的单例类的它在那里找到方法并执行它。

但是我们应该承认,有两个类的继承链,它们处于某种竞争状态,因为必须先遍历两个链中的一个。但是哪一个?是普通类还是单例类?

好吧,如果你更了解请告诉我,但代码似乎会说话:

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 的单例方法,我们可以看得更清楚:

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.

那些这种行为意味着类是单例类的实例?

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

如果你知道更多,请分享你的知识。这是一个非常有趣的话题:)

关于ruby - 为什么单例方法(AKA : class methods) are inherited?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55986625/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com