Класс.суперкласс = модуль, Module.class = Класс?

#ruby

#ruby

Вопрос:

Как это вычисляется? Это циклический

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

 Class.superclass = Module
Module.class = Class
  

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

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

Комментарии:

1. Или, если уж на то пошло Object.class=Class . ?? Класс объекта (корень в Ruby OM) является классом? Но класс еще даже не определен?

2. На самом деле это не совсем четко сформулированный вопрос, но, возможно, эта диаграмма поможет.

3. на диаграмме показаны суперклассы и собственные классы. Не к какому классу относится каждый объект на вашей диаграмме

Ответ №1:

Давайте взглянем на class.c файл исходного кода MRI:

 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 .

Ответ №2:

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 само по себе.

Ответ №3:

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