wmock
wmock

Reputation: 5492

Ruby Object Model - ancestors of a class

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

Answers (1)

Neil Slater
Neil Slater

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

Related Questions