Ruby inheritance and instances - ruby

I made a class User (which is an instance of Class), and made it inherit from class Person. What makes this considered not to be multiple inheritance? Doesn't it inherit instance methods like new from Class and any methods that Person offers?
In other words, how is this not multiple inheritance:
class User < class Person
some methods here...
end
when User already inherits all of Class's methods? Isn't the following what is going on under the hood?
class User < class Person and class Class
end

If you open irb you can check it yourself. Type User.superclass, you will see that User has only one superclass, which is Person. User will inherit the methods from Object because Person's superclass is Object

It is not "multiple inheritance" in usual way, but a simple chain of inheritance.
Ancestors cannot have own constructors unless you call them explicitly from initialize, and in complex hierarchies this can be very painful.
The main point is that there's only one instance object, that is shared and methods are mixed into it.
In ruby class hierarchy is always a tree. Even mixins, that may look like a multiple inheritance - internally are implemented as inheritance chain.
True multiple inheritance can be hard, for example, in C++:
class A {}
class B: public A{}
class C: public A{}
class D: public B, public C{}
How many instances of A should be inside D? (the "diamond problem")
Ruby avoids it by simply not having the cause.

Related

How do we talk about classes that do not inherit from the `Class` class in Ruby?

BasicObject, as far as I have read, is the parent class of all other classes in Ruby. However, it's not until further down in the hierarchy where the Class class is actually defined. As such, I'm having a hard time understanding how BasicObject can be a class at all.
Is the difference here just that there's a difference between a ruby Class in an abstract, object-oriented sense as opposed to classes that are actually instances of Class? Or is the hierarchy actually set up in a way where BasicObject is in fact an instance of Class? I feel pretty sure that's not the case.
If there are two meanings for the word "class" in Ruby, I feel like I lack the language to discuss the two types. If this is indeed the case, what can I call a class that is not an instance of Class?
You can treat all classes are instances of Class in the Ruby world. Worth remembering that everything in ruby is an object, including classes. Yes BasicObject is the top parent class of all classes in Ruby. The class of BasicObject being Class, is not the same as the parent class of BasicObject is Class.
To demonstrate, assume that we have a class Person defined.
Person.new.class is Person
Person.class is Class
Person.superclass is Object
Object.class is Class
Object.superclass is BasicObject
BasicObject.class is Class
BasicObject.superclass is nil
Proof of all classes in Ruby are in fact objects, you can get the object id of a class. BasicObject.object_id. In the general object-oriented context, a class of a class shouldn't make sense, unless classes are also objects.
As mind-bending as it sounds, it really is like that. BasicObject is a Class and Class is a BasicObject.
I don't think it's possible to express in ruby, so to make this work MRI direcly creates internal structures for these few fundamental classes and wires them in this cyclical manner.
void
Init_class_hierarchy(void)
{
rb_cBasicObject = boot_defclass("BasicObject", 0);
rb_cObject = boot_defclass("Object", rb_cBasicObject);
rb_gc_register_mark_object(rb_cObject);
/* resolve class name ASAP for order-independence */
rb_set_class_path_string(rb_cObject, rb_cObject, rb_fstring_lit("Object"));
rb_cModule = boot_defclass("Module", rb_cObject);
rb_cClass = boot_defclass("Class", rb_cModule);
rb_const_set(rb_cObject, rb_intern_const("BasicObject"), rb_cBasicObject);
RBASIC_SET_CLASS(rb_cClass, rb_cClass);
RBASIC_SET_CLASS(rb_cModule, rb_cClass);
RBASIC_SET_CLASS(rb_cObject, rb_cClass);
RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
}
As we can see, there are no two class types, user-facing one and "deep" one. It's the same entity.

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.

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.

Understanding Ruby Inheritance

I've been reading the Well Grounded Rubyist and it mentions how a class inherits the instance methods of its super class so that objects of the class will be able to call those instance methods. Here's an example:
class C
def run_instance_method
puts "This is an instance method."
end
def C.run_class_method
puts "This is a class method."
end
end
class D < C
end
Based on what I've read, it's always been described that class D would inherit just the instance methods of class C (in which case, the C::run_class_method would not be inherited by D). However, after running the above code, I notice that:
D.run_class_method # => "This is a class method."
Here's my guess as to why this is happening and please let me know if this is the correct understanding. If there is an instance d of class D and you try to run d.run_instance_method, that object will search its method-lookup path and see if that method is defined in its singleton class, its own class, or in its superclasses. Since run_instance_method is defined in class C, no issues will occur and run_instance_method will be called. For the class object D (which is a subclass of C and Object), if D.run_class_method is called, it'll again check the method lookup path for the D class object. Again, Ruby will find it in the class object C.
Is this reasoning accurate?
Class methods may be inherited and overridden just as instance methods can be. If your parent class defines a class method, the subclass inherits that method. That is, if your subclass does not define it's own class method, then it inherits from it's superclass.
As a recommendation: when invoking a class method with an explicit receiver, you should avoid relying on inheritance. Always invoke the class method through the class that defines it. Otherwise, it would be very difficult for someone who relies on your code to find the parent class which defines the class method.
Referring back to your original assumption: the invocation of a class method from a subclass it's possible because the class methods are instance methods of the eigenclass.
class C
# instance methods goes here
class << self # open the eigenclass
# class methods go here as instance methods of the eigenclass
end
end
In general, it's clearer to define class methods as individual singleton methods without explicitly opening the eigenclass.
For a clear explanation read The Ruby Programming Language by David Flanagan and Yukihiro Matsumoto
Not very exactly. There is another concept hidden here, called metaclass or eigenclass. The class method is inherited from eigenclass. See Ruby Hacking Guide for more information about it. ( Just search for "class methods" in the page if you don't want to read them all. )

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