David Kennell
David Kennell

Reputation: 1227

How do we talk about classes that do not inherit from the `Class` class in Ruby?

BasicObject, as far as I have read, is the parent class of all other classes in Ruby. However, it's not until further down in the hierarchy where the Class class is actually defined. As such, I'm having a hard time understanding how BasicObject can be a class at all.

Is the difference here just that there's a difference between a ruby Class in an abstract, object-oriented sense as opposed to classes that are actually instances of Class? Or is the hierarchy actually set up in a way where BasicObject is in fact an instance of Class? I feel pretty sure that's not the case.

If there are two meanings for the word "class" in Ruby, I feel like I lack the language to discuss the two types. If this is indeed the case, what can I call a class that is not an instance of Class?

Upvotes: 4

Views: 127

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230461

As mind-bending as it sounds, it really is like that. BasicObject is a Class and Class is a BasicObject.

I don't think it's possible to express in ruby, so to make this work MRI direcly creates internal structures for these few fundamental classes and wires them in this cyclical manner.

void
Init_class_hierarchy(void)
{
    rb_cBasicObject = boot_defclass("BasicObject", 0);
    rb_cObject = boot_defclass("Object", rb_cBasicObject);
    rb_gc_register_mark_object(rb_cObject);

    /* resolve class name ASAP for order-independence */
    rb_set_class_path_string(rb_cObject, rb_cObject, rb_fstring_lit("Object"));

    rb_cModule = boot_defclass("Module", rb_cObject);
    rb_cClass =  boot_defclass("Class",  rb_cModule);

    rb_const_set(rb_cObject, rb_intern_const("BasicObject"), rb_cBasicObject);
    RBASIC_SET_CLASS(rb_cClass, rb_cClass);
    RBASIC_SET_CLASS(rb_cModule, rb_cClass);
    RBASIC_SET_CLASS(rb_cObject, rb_cClass);
    RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
}

As we can see, there are no two class types, user-facing one and "deep" one. It's the same entity.

Upvotes: 2

Rein Avila
Rein Avila

Reputation: 405

You can treat all classes are instances of Class in the Ruby world. Worth remembering that everything in ruby is an object, including classes. Yes BasicObject is the top parent class of all classes in Ruby. The class of BasicObject being Class, is not the same as the parent class of BasicObject is Class.

To demonstrate, assume that we have a class Person defined.

  • Person.new.class is Person
  • Person.class is Class
  • Person.superclass is Object
  • Object.class is Class
  • Object.superclass is BasicObject
  • BasicObject.class is Class
  • BasicObject.superclass is nil

Proof of all classes in Ruby are in fact objects, you can get the object id of a class. BasicObject.object_id. In the general object-oriented context, a class of a class shouldn't make sense, unless classes are also objects.

Upvotes: 2

Related Questions