Reputation: 5492
I'm studying the Ruby Object Model from the book "Metaprogramming Ruby" and I understand the notion of how classes are Objects as well.
class A
end
A.ancestors # => [A, Object, Kernel, BasicObject]
A.class.ancestors # => [Class, Module, Object, Kernel, BasicObject]
What I'm confused about is that when I initially tried A.ancestors in irb, I expected the results that I got in A.class.ancestors - my thought process was: since A is a class, and a class is an instance of class Class, it's ancestor is Class. But Class doesn't seem to be an ancestor of A.
Would someone be able to clear up my confusion here?
Upvotes: 22
Views: 15194
Reputation: 27207
The class A
is an instance of Class
, and you can see that via A.class
The class of an instance of A is A
, and you access that via a = A.new; a.class
The method ancestors
is showing the class hierarchy that an object of that class has (or would have) as its inheritance.
There are two parallel class hierarchy models going on in your example, and they only impinge on each other because Ruby represents its classes as objects for you to inspect and modify.
There is no fundamental reason to need A.class.ancestors and A.ancestors to intersect at all - except Ruby also has a deep class model with simple roots, so in practice that is what you'll see.
In fact I couldn't find any counter-example, even nil does this:
NilClass.ancestors
=> [NilClass, Object, Kernel, BasicObject]
NilClass.class.ancestors
=> [Class, Module, Object, Kernel, BasicObject]
This one is more enlightening though:
BasicObject.ancestors
=> [BasicObject]
BasicObject.class.ancestors
=> [Class, Module, Object, Kernel, BasicObject]
Upvotes: 25