I don't quite get some things about the Ruby object model. First, is EVERYTHING in Ruby an instance of Class
? These all produce true:
p Object.instance_of?(Class)
p Class.instance_of?(Class)
p Module.instance_of?(Class)
p BasicObject.instance_of?(Class)
class Hello; end
p Hello.instance_of?(Class)
I can't quite get how is it possible, if Object
is a superclass of Class
, how can it be both a superclass of Class
and an instance of it at the same time (most diagrams on the Ruby Object Model clearly state this hierarchy)? Which allows for some crazyness like this:
p BasicObject.is_a?(Object) #=> true
where BasicObject.class
is Class
, and Class.is_a?(Object)
.
By the way, using Ruby 2.0.
First, is EVERYTHING in Ruby an instance of
Class
?
No, not everything is an instance of Class
. Only classes are instances of Class
.
There are lots of things which aren't instances of Class
: strings, for example, are instances of String
, not Class
. Arrays are instances of Array
, integers are instances of Integer
, floats are instances of Float
, true
is an instance of TrueClass
, false
is an instance of FalseClass
, nil
is an instance of NilClass
, and so on.
Every class is an instance of Class
, just like every string is an instance of String
.
if
Object
is a superclass ofClass
, how can it be both a superclass ofClass
and an instance of it at the same time (most diagrams on the Ruby Object Model clearly state this hierarchy)?
Magic.
Just like in most other languages, there are some core entities that are simply assumed to exist. They fall from the sky, materialize out of thin air, magically appear.
In Ruby, some of those magic things are:
Object
doesn't have a superclass, but you cannot define a class with no superclass, the implicit direct superclass is always Object
. [Note: there may be implementation-defined superclasses of Object
, but eventually, there will be one which doesn't have a superclass.]Object
is an instance of Class
, which is a subclass of Object
(which means that indirectly Object
is an instance of Object
itself)Class
is a subclass of Module
, which is an instance of Class
Class
is an instance of Class
None of these things can be explained in Ruby.
BasicObject
, Object
, Module
and Class
all need to spring into existence at the same time because they have circular dependencies.
Just because this relationship cannot be expressed in Ruby code, doesn't mean the Ruby Language Specification can't say it has to be so. It's up to the implementor to figure out a way to do this. After all, the Ruby implementation has a level of access to the objects that you as a programmer don't have.
For example, the Ruby implementation could first create BasicObject
, setting both its superclass
pointer and its class
pointer to null
.
Then, it creates Object
, setting its superclass
pointer to BasicObject
and its class
pointer to null
.
Next, it creates Module
, setting its superclass
pointer to Object
and its class
pointer to null
.
Lastly, it creates Class
, setting its superclass
pointer to Module
and its class
pointer to null
.
Now, we can overwrite BasicObject
's, Object
's, Module
's, and Class
's class
pointer to point to Class
, and we're done.
This is easy to do from outside the system, it just looks weird from the inside.
You should notice that:
p BasicObject.instance_of?(BasicObject)
prints false
.
That is, the expression BasicObject
is not an instance of BasicObject
, it is an instance of something else, that is, it is a Class
object, which represents an object that holds (for example) the class methods, such as new
.
For example:
p (BasicObject.new()).instance_of?(BasicObject)
prints true
, and
p (BasicObject.new()).instance_of?(Class)
prints false
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With