#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 и настраиваются таким образом при запуске, а не добавляются обычным способом добавления класса. Среда выполнения имеет право настраивать указатели так, как она хочет, и разработчик решил сделать это таким образом.