In a recent thread titled “Unexpected results from private_methods”, I
questioned the methods available for a BasicObject. That led to an
interesting comment about BasicObject’s place in the object model.
The comment (paraphrased) was:
BasicObject is a class, an instance of Class.
Class inherits from Object.
Almost everything in ruby is an object–including
classes. All objects inherit from Object.
Things are very “circular” at the top of the ruby object model.
BasicObject is an object, it inherits from Object. Object,
in turn, inherits from BasicObject, which means
BasicObject inherits from itself!
I get the conceptual drift, but I wonder about the practical
implications. So I ran a bit of code to try to understand better, and
just confused myself more. Specifically, I ran code to determine
BasicObject’s class, superclass and ancestors, and whether BasicObject
is an instance or kind of BasicObject, Object and/or Class.
The results SEEM inconsistent to me (probably because of my limited
understanding).
BasicObject’s class is Class
BasicObject’s superclass is
BasicObject’s ancestors are [BasicObject]
BasicObject kind of BasicObject? true
BasicObject instance of BasicObject? false
BasicObject kind of Object? true
BasicObject instance of Object? false
BasicObject kind of Class? true
BasicObject instance of Class? true
Do these results seem inconsistent to anyone else?
j
James D. Maher
[email protected]
1.) Which results seem inconsistent to you?
2.) What code did you write to produce those results?
~ jf
John F.
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: User John Feminella - Stack Overflow
John F. wrote in post #1011420:
1.) Which results seem inconsistent to you?
BasicObject’s superclass is nil, yet it is both a kind and instance of
Class.
BasicObject has no ancestors, yet it is a Class (which is an Object,
etc.)
2.) What code did you write to produce those results?
Code attached.
Jim M. wrote in post #1011440:
John F. wrote in post #1011420:
1.) Which results seem inconsistent to you?
BasicObject’s superclass is nil, yet it is both a kind and instance of
Class.
Every class is an instance of Class. No class is a subclass of
Class; that wouldn’t make sense.
BasicObject has no ancestors, yet it is a Class (which is an Object,
etc.)
That’s the point of BasicObject—to be the root of the entire class
hierarchy. Again, seems like you’re confusing subclassing with
instantiation, which is easy to do when classes (little ‘c’) are also
first-class objects (little ‘o’).
BasicObject’s class is Class
because it’s a class.
BasicObject’s superclass is
BasicObject’s ancestors are [BasicObject]
because it’s the root of the class hierarchy.
BasicObject kind of BasicObject? true
because BasicObject is an instance of Class, and Class < Module < Object
< BasicObject.
BasicObject instance of BasicObject? false
because BasicObject is an instance of Class, which is a subclass of
BasicObject, and not an instance of BasicObject itself.
BasicObject kind of Object? true
BasicObject instance of Object? false
BasicObject kind of Class? true
BasicObject instance of Class? true
Following the reasoning above should make this make sense to you.
The real circularity is this:
Class.superclass
=> Module
Module.superclass
=> Object
Object.class
=> Class
…that is, Object is an instance of its subclass:
Object.instance_of? Class
=> true
Class < Object
=> true
Kevin Bullock wrote in post #1011446:
… seems like you’re confusing subclassing with
instantiation …
I think you’re right.
Let me restate, just so I’ll remember.
BasicObject’s class is Class
because BasicObject is an instance of Class.
BasicObject’s superclass is
because BasicObject is NOT a subclass of anything.
BasicObject’s ancestors are [BasicObject]
because BasicObject is NOT a subclass of anything.
BasicObject kind of BasicObject? true
because BasicObject is an instance of Class,
and Class is a subclass of Module,
and Module is a subclass of Object,
and Object is a subclass of BasicObject.
BasicObject instance of BasicObject? false
because BasicObject is an instance of Class,
and an object can only be an instance of one thing.
BasicObject kind of Object? true
because BasicObject is an instance of Class,
and Class < Module < Object.
BasicObject instance of Object? false
because BasicObject is an instance of Class,
and an object can only be an instance of one thing.
BasicObject kind of Class? true
because BasicObject is an instance of Class.
BasicObject instance of Class? true
because BasicObject is an instance of Class.
I’ll leave it at that for now, and try to improve my understanding so
that I more readily make the distinction between instance and
subclass.
(and I’ll leave for another day the cicularity that Object is an
instance of its subclass Class …)
Thanks,
j
Let me restate, just so I’ll remember.
I doubt that memorizing that will be useful. Understanding the
principles is much more important than the results of applying the
principles. However, because of the circularity at the top of the ruby
object
model, applying the principles can lead to some weird results.
I’ll leave it at that for now, and try to improve my understanding
so that I more readily make the distinction between
instance and subclass.
Animal
end
Dog < Animal
end
d = Dog.new
Dog is a subclass of Animal, and d is an instance of dog.
But you also have to remember that all objects are an instance of some
class. Because most things in ruby are an object, it follows that most
things in ruby are an instance of some class. Dog is a ruby object,
so it must also be an instance of some class. That class is Class:
Dog = Class.new do
def bark
puts ‘woof’
end
end
d = Dog.new
d.bark
–output:–
woof
Note that Dog.new is called, but the Dog class does not define a new
method. Where does that method come from? Since Dog is an instance of
Class, it can call any methods defined in Class, and new() is defined in
Class. But Dog can also define it’s own instance methods? Strangely,
in ruby not all objects share the same methods, i.e. the methods defined
by their class. You may have seen something like this before:
ddef d.talk
puts ‘hello’
end
d.talk
–output:–
hello
rover = Dog.new
rover.talk
rover = Dog.new
rover.sleep #error
Now here is a question to ponder: Class is an object, just like most
things in ruby. So what class is Class an instance of?