The Class Superclass and Subclass Structure of Ruby [duplicate] - ruby

This question already has answers here:
The Class/Object Paradox confusion
(6 answers)
Closed 9 years ago.
The Class has the superclass Module, which has the superclass Object, which has the superclass BasicObject, which is an instance of Class. And Class is again a subclass of Module.
I'm really confused regarding this.(the above was gleaned from using the .class and .superclass methods on each of the above objects)
Can anyone explain to me what exactly is going on here?

The phrase "instance of" is a small but significant part of the mental gymnastics you need to do here.
That, and objects of type Class, and a class called Object.
If you can understand these, at least while repeating to yourself slowly, then you have got it:
Object.new creates an instance of class Object
Object is a reference to the class Object, which is itself an object of class Class
Class is a reference the class Class, which is also an object of class Class (!)
Class.new creates an instance of class Class.
This is part of what happens under the hood when you write class Foo
In fact Foo = Class.new( String ) is much the same as class Foo < String; end
The class hierarchy of Class, Module, Object is an implementation detail in Ruby. Almost all classes inherit from Object, so it is no real surprise that Class does so too.
The rest is just repeated use and experience.
It is worth noting something else going on here: The labels in the code you type are symbols/variable names, which are pointers to the underlying objects which have types and contain data. There is no requirement to use those labels directly, they are pretty much the same as any other Ruby variable:
o_klass = Object
o_instance = o_klass.new
o_instance.class
=> Object

Related

What is the root of a class? [duplicate]

I understand that all classes in ruby are instances of metaclass Class. And that "regular" objects are instances of these classes (the instances of metaclass Class).
But I keep wondering, I mean classes are root of objects, classes are themselves instances of Class (called metaclass because its instances are classes). I saw in some blogs some overriding of method new, of class Class.
So Class behaves as a class, but its instances are classes. So it seems we have a circle, it looks likes class Class is an instance of itself.
I'm clearly missing a point here. What is the origin of class Class?
Here's an example that's confusing me:
class Class
def new
#something
end
end
But keyword class implies an instance of class Class. So how do this work?
how do this work
Easy: it doesn't. Not in Ruby, anyway.
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.
Once they do exist, however, it is perfectly possible to implement most of their behavior in plain Ruby. You only need very barebones versions of those classes, thanks to Ruby's open classes, you can add any missing functionality at a later time.
In your example, the class Class is not creating a new class named Class, it is reopening the existing class Class, which was given to us by the runtime environment.
So, it is perfectly possible to explain the default behavior of Class#new in plain Ruby:
class Class
def new(*args, &block)
obj = allocate # another magic thing that cannot be explained in Ruby
obj.initialize(*args, &block)
return obj
end
end
[Note: actually, initialize is private, so you need to use obj.send(:initialize, *args, &block) to circumvent the access restriction.]
BTW: Class#allocate is another one of those magic things. It allocates a new empty object in Ruby's object space, which is something that cannot be done in Ruby. So, Class#allocate is something that has to be provided by the runtime system as well.
There is a meta-circularity given by the "twist" link. It is the built-in superclass link from the root's eigenclass to the Class class. This can be expressed by
BasicObject.singleton_class.superclass == Class
A clue to understanding the .class map is seeing this map as derived from the eigenclass and superclass links: for an object x, x.class is the first class in the superclass chain of x's eigenclass. This can be expressed by
x.class == x.eigenclass.superclass(n)
where eigenclass is a "conceptual alias" of singleton_class
(resistant to issues with immediate values), y.superclass(i) means i-th superclass of y and n is smallest such that x.eigenclass.superclass(n) is a class. Equivalently, eigenclasses in the superclass chain of x.eigenclass are skipped (see rb_class_real which also reveals that in MRI, even superclass links are implemented indirectly – they arise by skipping "iclasses").
This results in that the class of every class (as well as of every eigenclass) is constantly the Class class.
A picture is provided by this diagram.
The metaclass confusion has 2 main sources:
Smalltalk. The Smalltalk-80 object model contains conceptual inconsistencies that are rectified by the Ruby object model. In addition, Smalltalk literature uses dialectics in terminology, which unfortunately has not been sufficiently remedied in the Ruby literature.
The definition of metaclass. At present, the definition states that metaclasses are classes of classes. However, for so called "implicit metaclasses" (the case of Ruby and Smalltalk-80) a much more fitting definition would be that of meta-objects of classes.
Yes, Class is an instance of itself. It's a subclass of Module, which is also an instance of class, and Module is a subclass of Object, which is also an instance of Class. It is indeed quite circular — but this is part of the core language, not something in a library. The Ruby runtime itself doesn't have the same limits thast you or I do when we're writing Ruby code.
I've never heard the word "metaclass" used to talk about Class, though. It isn't used much in Ruby at all, but when it is, it's usually a synonym for what's officially called a "singleton class of an object," which is an even more confusing topic than Object-Module-Class triangle.
Though it is a little out of date, this article by _why may help in understanding the behavior. You can find an even deeper dive into the subject in Paolo Perrotta's Metaprogramming Ruby.

Why is EVERYTHING an instance of Class in Ruby? [duplicate]

This question already has answers here:
Ruby metaclass confusion
(4 answers)
Closed 7 years ago.
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 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)?
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.
All of your examples were by definition classes. Classes are also objects. But what you didn't do was look at an instance of a class:
p Object.new.class
p Hello.new.class
Classes define the form of an object, and by definition, a class is a Class. But when you instantiate class into an object, the object is the new type. But you can still see that the object's class is itself Class:
p Hello.new.class.class

Initialization Order of Ruby class Class and class Module [duplicate]

I understand that all classes in ruby are instances of metaclass Class. And that "regular" objects are instances of these classes (the instances of metaclass Class).
But I keep wondering, I mean classes are root of objects, classes are themselves instances of Class (called metaclass because its instances are classes). I saw in some blogs some overriding of method new, of class Class.
So Class behaves as a class, but its instances are classes. So it seems we have a circle, it looks likes class Class is an instance of itself.
I'm clearly missing a point here. What is the origin of class Class?
Here's an example that's confusing me:
class Class
def new
#something
end
end
But keyword class implies an instance of class Class. So how do this work?
how do this work
Easy: it doesn't. Not in Ruby, anyway.
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.
Once they do exist, however, it is perfectly possible to implement most of their behavior in plain Ruby. You only need very barebones versions of those classes, thanks to Ruby's open classes, you can add any missing functionality at a later time.
In your example, the class Class is not creating a new class named Class, it is reopening the existing class Class, which was given to us by the runtime environment.
So, it is perfectly possible to explain the default behavior of Class#new in plain Ruby:
class Class
def new(*args, &block)
obj = allocate # another magic thing that cannot be explained in Ruby
obj.initialize(*args, &block)
return obj
end
end
[Note: actually, initialize is private, so you need to use obj.send(:initialize, *args, &block) to circumvent the access restriction.]
BTW: Class#allocate is another one of those magic things. It allocates a new empty object in Ruby's object space, which is something that cannot be done in Ruby. So, Class#allocate is something that has to be provided by the runtime system as well.
There is a meta-circularity given by the "twist" link. It is the built-in superclass link from the root's eigenclass to the Class class. This can be expressed by
BasicObject.singleton_class.superclass == Class
A clue to understanding the .class map is seeing this map as derived from the eigenclass and superclass links: for an object x, x.class is the first class in the superclass chain of x's eigenclass. This can be expressed by
x.class == x.eigenclass.superclass(n)
where eigenclass is a "conceptual alias" of singleton_class
(resistant to issues with immediate values), y.superclass(i) means i-th superclass of y and n is smallest such that x.eigenclass.superclass(n) is a class. Equivalently, eigenclasses in the superclass chain of x.eigenclass are skipped (see rb_class_real which also reveals that in MRI, even superclass links are implemented indirectly – they arise by skipping "iclasses").
This results in that the class of every class (as well as of every eigenclass) is constantly the Class class.
A picture is provided by this diagram.
The metaclass confusion has 2 main sources:
Smalltalk. The Smalltalk-80 object model contains conceptual inconsistencies that are rectified by the Ruby object model. In addition, Smalltalk literature uses dialectics in terminology, which unfortunately has not been sufficiently remedied in the Ruby literature.
The definition of metaclass. At present, the definition states that metaclasses are classes of classes. However, for so called "implicit metaclasses" (the case of Ruby and Smalltalk-80) a much more fitting definition would be that of meta-objects of classes.
Yes, Class is an instance of itself. It's a subclass of Module, which is also an instance of class, and Module is a subclass of Object, which is also an instance of Class. It is indeed quite circular — but this is part of the core language, not something in a library. The Ruby runtime itself doesn't have the same limits thast you or I do when we're writing Ruby code.
I've never heard the word "metaclass" used to talk about Class, though. It isn't used much in Ruby at all, but when it is, it's usually a synonym for what's officially called a "singleton class of an object," which is an even more confusing topic than Object-Module-Class triangle.
Though it is a little out of date, this article by _why may help in understanding the behavior. You can find an even deeper dive into the subject in Paolo Perrotta's Metaprogramming Ruby.

Implement Ruby's Object#class method [duplicate]

This question already has answers here:
How do I get the class of a BasicObject instance?
(8 answers)
Closed 9 years ago.
I'm extending BasicObject, and I'd like to implement Object#class method. I'm not sure how to do this other than hard-coding the return value like this:
class MyObject < BasicObject
def class
::Kernel::eval "::MyObject"
end
end
MyObject.new.class
#=> MyObject
With this solution, any class that inherits from MyObject would have to overwrite this method in order to keep it accurate. Is there a better way?
It's not possible to implement this method in Ruby. You need access to three things that you cannot access from Ruby:
the class pointer
the superclass pointer
the virtual class flag (include classes and singleton classes are virtual classes)
Object#class works something like this:
class Object
def class
c = self.__class__
c = c.__superclass__ while c.__virtual__?
c
end
end
There's also Class#superclass:
class Class
def superclass
c = self.__superclass__
c = c.__superclass__ while c.__virtual__?
c
end
end
And since there is no way to get the class pointer (remember: the class method does not return it) and there is no way to get the superclass pointer (remember: the superclass method doesn't return it either) and there is no way for you to check whether a class is virtual, it is impossible to write this method in Ruby.
You need some sort of privileged access to the runtime internals to do that.
Since you are refusing to inherit Object, you are missing almost all basic methods, including class or ancestors. You would need to hard code everything. Besides the minimal syntax, everything is gone. Think of it as tabla rasa. There is no other method on which you can build your methods.
Ruby is designed to have all objects inherit from Object, and going against that does not result in useful result.
I was directed towards this possible duplicate question: How do I get the class of a BasicObject instance?
The solution provided to that question solves my problem. Thanks!

Questions about OBJECTS in Ruby

I'm reading 'metaprogramming in ruby'
its such an EXCELLENT book. Seriously, it talks about stuff that I never hear mentioned elsewhere.
I have a few specific questions however about objects (I'm in the first few chapters)
I understand that the RubyGems gem installs the method 'gem' to the module Kernel so that it shows up on every object. Is there a reason they didnt put it into the Object class?
He talks about how when ruby looks for the method it always goes right then up. What exactly does 'up' mean? I see it in the diagram, its just that I dont really understand the purpose of 'up'. he doesnt explain that part much.
What is the point of the Object class? How come those methods cant be just placed into Class? If every object belongs to a class (even if its Class), then what is the point of object, basicobject, and kernel?
String, Array, blah blah are obviously an instance of Class. Class is also an instance of itself. So if Class is an instance of Class.... how does it also inherit from Object? Where in the code does it relates to BOTH Class and Object?
I know kernel contains methods such as puts that can be used everywhere, and this relates to question 1, but why cant they just condense it and put it all into Object... where it would seem everything inherits from object anyway
Both would work, but typically methods on Object should only be methods that deal with a particular object. Puting things in the Kernel module are less about about object and more global.
I assume it means "up the inheritance chain". So it looks for the method on the child class, then on that classes parent class until it finds one or runs out of parent classes.
Object is the base class of all objects, naturally (For ruby 1.8 at least). The crazy part is that a class is actually an instance of the Class class. (you follow that?) So adding instance methods to Class would add methods to class objects, but not instances of those classes.
Nearly everything in ruby is an object. Class.superclass is actually Module (which is like a class you can't instantiate) and Module.superclass returns Object. So Class < Module < Object is the inheritance chain if the Class class. (For ruby 1.8 at least)
More convention than anything. Since Object can get rather HUGE, it's customary to put things into modules and then combine those modules later. If the method doesn't deal with an instance of an object directly as self then the method doesn't belong directly in Object. More global non-object instance methods like gem go in the Kernel module to signify that they are simply methods available everywhere.
Some more about class objects and inheritance...
class Foo < Bar
def hi
puts 'Hi!'
end
end
What this does is really quite awesome. It defines a class object, of course. Now this class object is configured to have a name Foo, a parent class Bar and a method hi. This info is sort of like this class object's meta data.
Now the class object Foo itself is an instance of Class. But Foo defines a class that inherits from Bar. The Class class defines a data structure to store this meta data about a class.
You can think of the Class class sorta kinda being defined like this:
class Class < Module
# fictional method called on class creation
def set_meta_data(name, superclass, methods)
#name = name
#superclass = superclass
#methods = methods
end
# fictional way in which an instance might be created
def new
instance = Object.new
instance.superclass = #superclass
instance.addMethods(#methods)
instance
end
end
So a class object itself would inherit from Class but it would create objects that do not.
Thinking of classes as objects can be a bit mind bending in this way, but this also why ruby is awesome.
For 1 and 5, pseudo-keyword commands tend to go into Kernel rather than Object.
For 2, it makes sense for sub-classes to be "down" relative to their parent class (sub literally meaning "beneath"). Therefore if you're heading for a parent class and its ancestors, you have to go "up".
For 3, an object object is not an instance of Class, it is an instance of Object.
For 4, what's wrong with something being an instance of Class and inheriting from Object? All classes inherit from Object.

Resources