Filip Bartuzi
Filip Bartuzi

Reputation: 5931

Why does `BasicObject` answer methods `superclass` and `class`?

If Object < BasicObject, and #superclass and #class are defined in Object, how it possible that class A < BasicObject answers to A.superclass and A.class? A.ancestors: [A, BasicObject]

Going further (according to new answers):

If A is an instance of Object why doesn't it have it in its ancestors?

Class B;end
B.ancestors # => [B, Object, Kernel, BasicObject]

SuperClass might be defined in Kernel, but A doesn't have Kernel in its ancestors.

Kernel is included in Object (from object.rb):

class Object < BasicObject
  include Kernel
end

P.S This git issue confused me enough to ask about it

Upvotes: 4

Views: 158

Answers (4)

Aetherus
Aetherus

Reputation: 8898

BasicObject has a minimal set of instance methods, but it has as many common class methods (instance methods of Class class) as other classes, that's why you can call BasicObject.class. Also remember that BasicObject itself is an Object, and all instances of Object have the method class, so does BasicObject.

Upvotes: 0

sawa
sawa

Reputation: 168199

It is because A (as well as BasicObject) is an instance of the Class class, on which superclass is defined, and Class is a subclass of Object, which includes Kernel, on which class is defined.

BasicObject.method(:superclass).owner # => Class
BasicObject.method(:class).owner # => Kernel

Upvotes: 3

Yu Hao
Yu Hao

Reputation: 122443

class A < BasicObject
end

Here, the class A is itself an instance of the class Class.

A.class
#=> Class

A answers to .class and .superclass because Class supports them.

What you are thinking is an instance of A, in that case:

A.new
(Object doesn't support #inspect)
=>

Upvotes: 2

tompave
tompave

Reputation: 12427

Your assumptions are not correct.

#class is defined as an instance method of Kernel:

From: object.c (C Method):
Owner: Kernel
Visibility: public
Number of lines: 5

VALUE
rb_obj_class(VALUE obj)
{
    return rb_class_real(CLASS_OF(obj));
}

and superclass is defined as an instance method of Class:

From: object.c (C Method):
Owner: Class
Visibility: public
Number of lines: 17

VALUE
rb_class_superclass(VALUE klass)
{
    VALUE super = RCLASS_SUPER(klass);

    if (!super) {
    if (klass == rb_cBasicObject) return Qnil;
    rb_raise(rb_eTypeError, "uninitialized class");
    }
    while (RB_TYPE_P(super, T_ICLASS)) {
    super = RCLASS_SUPER(super);
    }
    if (!super) {
    return Qnil;
    }
    return super;
}

Upvotes: 0

Related Questions