2011-04-24 20 views
10

¿Cómo se calcula eso? Es circularClass.superclass = Module, Module.class = ¿Clase?

Actualización: (en IRB)

Class.superclass = Module 
Module.class = Class 

¿Cómo es posible decir que la clase de un módulo es de clase, cuando la clase es subclase módulos? Es una cosa circular, de pollo y huevo.

Objeto: misma pregunta: Objeto es el objeto raíz en el modelo de objetos. ¿Cómo puede su clase ser Clase, dado que el objeto Clase aún no existe?

+0

O para el caso 'Object.class = Class'. ?? La clase Object (la raíz en Ruby OM) es Class? ¿Pero la clase aún no se ha definido? – Vassilis

+0

Esta no es realmente una pregunta bien definida, pero tal vez [este diagrama] (http://phrogz.net/RubyLibs/RubyMethodLookupFlow.png) ayude. – Phrogz

+0

el diagrama muestra superclases y clases propias. No de qué clase es cada objeto en tu diagrama – Vassilis

Respuesta

10

Vamos a echar un vistazo al archivo class.c del código fuente de resonancia magnética:

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; 
} 

Estas definiciones en ruby.h son muy importantes, también:

#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) 

Tenga en cuenta que Object, Module y Class son derivado de BasicObject. De hecho,

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

Esos objetos se define de forma simultánea y todos ellos tienen RBASIC(*)->klass = rb_cClass.

+0

Aha, ¡así que esta información acabo de arrancar! Gracias – Vassilis

3

x.superclass y x.class tienen una semántica diferente. Observe:

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 no tiene superclass porque ... 3 no es una clase o algo parecido. Pero 3.class significa la clase en la que 3 es una instancia de.

Por lo tanto, lo que debería corresponder a Class.superclass no es Module.class, sino Module sí mismo.

2

La dependencia circular funciona porque todas estas son clases integradas. Son parte del tiempo de ejecución Ruby básico y están configurados de esta manera en la puesta en marcha y no se agregan en la forma en que normalmente se agregaría una clase. El tiempo de ejecución tiene el poder de configurar los punteros como lo desee, y el diseñador eligió hacerlo de esta manera.