Я немного покопался, и функция ancestor
, похоже, пересекает член c-struct RClass.super, так же как и метод looup .Поэтому, когда я делаю
class OtherClass end
obj = OtherClass.new
obj.class.singleton_class.singleton_class.ancestors =>
[#<Class:#<Class:OtherClass>>, \
#<Class:#<Class:Object>>, \
#<Class:#<Class:BasicObject>>, \
#<Class:Class>, \
#<Class:Module>, \
#<Class:Object>, \
#<Class:BasicObject>, \
Class, \
Module, \
Object, \
Kernel, \
BasicObject]
BasicObject
^ +---------+ +--------+
| | | | |
Kernel | #<Class:BasicObject> | #<Class:#<Class:BasicObject>>
^ | ^ | ^
| | | | |
Object | #<Class:Object> | #<Class:#<Class:Object>>
^ | ^ | ^
| | | | |
+-------+ | +--------+ | |
| | | | |
Module | #<Class:Module> | |
^ | ^ | |
| | | | |
Class | #<Class:Class> | |
^ | ^ | |
+---+ +--------+ |
|
obj--->OtherClass --->#<Class:OtherClass>--->#<Class:#<Class:OtherClass>>
, это означает, что вертикальные стрелки на диаграмме можно рассматривать как обход RClass.super
c-членов.С другой стороны, горизонтальные стрелки должны быть связаны с RBasic.klass
, однако код Ruby выглядит асимметричным.
...
|
obj---> OtherClass
Когда создается класс-одиночка, первый RBasic.klass
получитRClass.super
нового синглтон-класса.
... ...
Object #<Class:Object>
^ ^
| |
OtherClass |
^ |
| |
obj--->#<Class:#OtherClass:0x...> ->#<Class:OtherClass> -+
^-+
и переход на один шаг дальше синглтона синглтона выглядит следующим образом:
... ... ...
Object #<Class:Object> #Class<#<Class:Object>>
^ ^ ^
| | |
OtherClass | |
^ | |
| | |
obj-->#<Class:#OtherClass:0x...>-->#<Class:OtherClass>-->#<Class:#<Class:OtherClass>>-+
^-+
Значение / использование одноэлементного классаПонятно, однако значение / использование метаклассов немного эзотерично.