Class.superclass = Module, Module.class = Class? - PullRequest
10 голосов
/ 24 апреля 2011

Как это вычисляется? Это круглое

Обновление: (в irb)

Class.superclass = Module
Module.class = Class

Как можно сказать, что классом модуля является класс, а классом является низший класс модулей? Это круглая курица и яйцо.

Объект: тот же вопрос: Объект является корневым объектом в объектной модели. Как его класс может быть Class, поскольку объект Class еще даже не существует?

Ответы [ 3 ]

10 голосов
/ 24 апреля 2011

Давайте посмотрим на файл class.c исходного кода МРТ:

void Init_class_hierarchy(void)
{
    id_attached = rb_intern("__attached__");

    rb_cBasicObject = boot_defclass("BasicObject", 0);
    /* boot_defclass is defined as boot_defclass(const char *name, VALUE super) */
    rb_cObject = boot_defclass("Object", rb_cBasicObject);
    rb_cModule = boot_defclass("Module", rb_cObject);
    rb_cClass =  boot_defclass("Class",  rb_cModule);

    /* Very important line: */
    RBASIC(rb_cClass)->klass
          = RBASIC(rb_cModule)->klass
          = RBASIC(rb_cObject)->klass
          = RBASIC(rb_cBasicObject)->klass
          = rb_cClass;
 }

Эти определения в ruby.h также очень важны:

#define R_CAST(st)   (struct st*)
#define RBASIC(obj)  (R_CAST(RBasic)(obj))
#define ROBJECT(obj) (R_CAST(RObject)(obj))
#define RCLASS(obj)  (R_CAST(RClass)(obj))
#define RMODULE(obj) RCLASS(obj)

Обратите внимание, что Object, Module и Class являются производными от BasicObject. Действительно,

irb(main):001:0> BasicObject.superclass
=> nil

Эти объекты определены одновременно, и все они имеют RBASIC(*)->klass = rb_cClass.

3 голосов
/ 24 апреля 2011

x.superclass и x.class имеют разную семантику. Обратите внимание:

irb(main):003:0> 3.superclass
NoMethodError: undefined method `superclass' for 3:Fixnum
    from (irb):3
    from :0
irb(main):004:0> 3.class
=> Fixnum

3 не имеет superclass, потому что ... 3 не класс или что-то подобное. Но 3.class означает класс, экземпляром которого является 3.

Итак, вещь, которая должна соответствовать Class.superclass, это не Module.class, а Module сама.

2 голосов
/ 09 мая 2012

Круговая зависимость работает, потому что это все встроенные классы.Они являются частью основной среды исполнения Ruby и настраиваются таким образом при запуске и не добавляются так, как вы обычно добавляете класс.Среда выполнения имеет право устанавливать указатели так, как хочет, и дизайнер решил сделать это таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...