[英]Singleton class of singleton class of BasicObject in Ruby
This is mostly an “academic” one but here it goes: 这主要是一个“学术”的,但在这里:
According to this Ruby eigenclass diagram (slightly edited): 根据这个Ruby eigenclass图(略加编辑):
BasicObject.singleton_class.singleton_class.superclass
is Class
. BasicObject.singleton_class.singleton_class.superclass
是Class
。
However, running this on a Ruby interpreter (Ruby v2.5.1), it turns out that BasicObject.singleton_class.singleton_class.superclass
is #<Class:Class>
and not Class
. 但是,在Ruby解释器(Ruby v2.5.1)上运行它,结果是
BasicObject.singleton_class.singleton_class.superclass
是#<Class:Class>
而不是Class
。 Therefore, is the diagram lying or am I missing something? 因此,图表是说谎还是我遗漏了什么?
The diagram is from a user I chatted with at Ruby IRC in Freenode. 该图来自我在Freenode的Ruby IRC聊天的用户。 However, it's been quoted multiple times to many other users and it's been treated as the Ruby object model bible.
但是,它被多次引用给许多其他用户,它被视为Ruby对象模型圣经。
The behavior of the Ruby interpreter makes perfect sense because: Ruby解释器的行为非常有意义,因为:
Child
class extends a Parent
, Ruby sets it up so that the singleton class #<Class:Child>
extends #<Class:Parent>
as well; Child
类扩展Parent
,Ruby会对其进行设置,以便单例类#<Class:Child>
扩展#<Class:Parent>
; and BasicObject.singleton_class
is a subclass of Class
, so BasicObject.singleton_class.singleton_class
will be a subclass of #<Class:Class>
BasicObject.singleton_class
是Class
的子Class
,因此BasicObject.singleton_class.singleton_class
将是#<Class:Class>
的子#<Class:Class>
Verifying the equality: 验证平等:
BasicObject.singleton_class.singleton_class.superclass.equal?(Class.singleton_class)
#=> true
This leads to the next question – why does #<Class:BaseObject>
extend Class
in the first place? 这导致了下一个问题 - 为什么
#<Class:BaseObject>
扩展Class
? Following the rule above, since BaseObject
has no superclass – that is, BaseObject.superclass
is nil
– the logical thing would be for its singleton class to not have a superclass either. 遵循上面的规则,因为
BaseObject
没有超类 - 也就是说, BaseObject.superclass
是nil
- 逻辑上的东西就是它的单例类也没有超类。
The answer is that #<Class:BaseObject>
extending Class
ensures consistency in the inheritance hierarchy when it comes to singleton classes. 答案是
#<Class:BaseObject>
Class
确保了单例类时继承层次结构的一致性。 Take this Ruby object for example: 以这个Ruby对象为例:
obj = "a string"
It is a well-established notion that instead of obj
being simply an instance of String
, we can think of it as an (only) instance of its own singleton class, which in turn is a subclass of String
. 这是一个公认的概念,我们可以将它视为它自己的单例类的一个(唯一的)实例而不是
obj
只是一个String
的实例,而这个实例又是String
的子类。 That is: 那是:
obj.class.equal?(obj.singleton_class.superclass)
#=> true
It seems only logical that the same should apply to class instances as well. 同样适用于类实例似乎也是合乎逻辑的。 But it does not, because it contradicts the rule mentioned above, where the superclass of a singleton class of a
Child
class is the singleton class of its Parent
class. 但它没有,因为它与上面提到的规则相矛盾,其中
Child
类的单例类的超类是其Parent
类的单例类。
class Foo; end
Foo.class
#=> Class
Foo.singleton_class.superclass
#=> #<Class:Object> <-- not equal to Class!
# because:
Foo.superclass
#=> Object
But it is possible to resolve this contradiction by placing Class
at the top of the singleton class inheritance hierarchy: 但是可以通过将
Class
放在单例类继承层次结构的顶部来解决这个矛盾:
Foo.singleton_class.superclass
#=> #<Class:Object>
Foo.singleton_class.superclass.superclass
#=> #<Class:BasicObject>
Foo.singleton_class.superclass.superclass.superclass
#=> Class
This way, even though Foo.singleton_class.superclass
is not equal to Foo.class
, by walking up the inheritance chain, it does get there eventually... 这样,即使
Foo.singleton_class.superclass
不等于Foo.class
,通过走向继承链,它最终会到达那里......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.