Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby Object Model - ancestors of a class

Tags:

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?

like image 655
wmock Avatar asked Mar 15 '13 13:03

wmock


People also ask

What is ancestor in Ruby?

ancestors is a class method in Ruby that returns an array of classes and modules commonly known as the ancestors chain. The order of the elements in this array are listed in a hierarchy of increasing parent rank. puts String.ancestors# => [String, Comparable, Object, Kernel, BasicObject]

What is the Ruby object model?

Ruby is a pure object-oriented language, which means that in the Ruby language, everything is an object. These objects, regardless of whether they are strings, numbers, classes, modules, etc., operate in a system called The Object Model. Ruby offers a method called the object_id , which is available to all objects.

What is the difference between a class and an object Ruby?

An object is a unit of data. A class is what kind of data it is.

Is a class an object in Ruby?

Object is the default root of all Ruby objects. Object inherits from BasicObject which allows creating alternate object hierarchies. Methods on Object are available to all classes unless explicitly overridden.


1 Answers

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]
like image 83
Neil Slater Avatar answered Nov 07 '22 19:11

Neil Slater