Reputation: 5931
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
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
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
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
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