Поведение интерпретатора Ruby имеет смысл, потому что:
- Когда класс
Child
расширяет Parent
, Ruby устанавливает его так, чтобы синглтон-класс #<Class:Child>
также расширял #<Class:Parent>
; и
BasicObject.singleton_class
является подклассом Class
, поэтому BasicObject.singleton_class.singleton_class
будет подклассом #<Class:Class>
Проверка равенства:
BasicObject.singleton_class.singleton_class.superclass.equal?(Class.singleton_class)
#=> true
Это приводит к следующему вопросу & ndash; почему #<Class:BaseObject>
расширяет Class
в первую очередь? Следуя приведенному выше правилу, поскольку BaseObject
не имеет суперкласса - ndash; то есть BaseObject.superclass
- это nil
& ndash; логично было бы, чтобы у его синглтон-класса не было и суперкласса.
Ответ таков: #<Class:BaseObject>
расширение Class
обеспечивает согласованность в иерархии наследования, когда речь идет об одноэлементных классах. Возьмите этот объект Ruby, например:
obj = "a string"
Хорошо известно, что вместо obj
, являющегося просто экземпляром String
, мы можем рассматривать его как (единственный) экземпляр своего собственного синглтон-класса, который, в свою очередь, является подклассом String
. То есть:
obj.class.equal?(obj.singleton_class.superclass)
#=> true
Кажется логичным, что то же самое должно относиться и к экземплярам классов. Но это не так, потому что это противоречит упомянутому выше правилу, когда суперкласс класса-одиночки класса Child
- это класс-одиночка его класса Parent
.
class Foo; end
Foo.class
#=> Class
Foo.singleton_class.superclass
#=> #<Class:Object> <-- not equal to Class!
# because:
Foo.superclass
#=> Object
Но это противоречие можно разрешить, поместив Class
на вершину иерархии наследования синглтон-классов:
Foo.singleton_class.superclass
#=> #<Class:Object>
Foo.singleton_class.superclass.superclass
#=> #<Class:BasicObject>
Foo.singleton_class.superclass.superclass.superclass
#=> Class
Таким образом, хотя Foo.singleton_class.superclass
не равно Foo.class
, пройдя по цепочке наследования, он в конечном итоге доберется до места ...