What is the relationship between the metaclass of Base and Derived class in Ruby? - ruby

In Ruby, we could use super within singleton method to call the corresponding super class's singleton method, like the following code shows.
class Base
def self.class_method
puts "Base class method"
end
end
class Derived < Base
def self.class_method
puts "Derived class method"
super
end
end
Derived.class_method
# Derived class method
# Base class method
However, I don't seem quite get how that call to super within Derived.class_method could reach Base.class_method. I'd assume that class_method is defined on their metaclass, does that mean their metaclass has parent/child relationship? (I can't quite confirm that by experiments)
Update: I'm asking this question because I remembered seeing somewhere there's some kind of relationship bettwen base and derived class' metaclass (but I can't find it any more). In addition to know how actually super works, I'd also like to confirm whether the two metaclasses are totally separate or not.

There are four class objects in play here:
<Class>---class---><Class>
Base #Base
^ ^
| |
| |
super super
| |
| |
<Class> <Class>
Derived---class--->#Derived
Nomenclature:
<...> is the class of each object.
The name of the class is on the second line.
If the name starts with #, it's the eigenclass (aka singleton class).
super points to a class's superclass
class points to the class's class.
When you call Derived.class_method, Ruby follows the "right one and then up" rule: First go to the object's class, then follow the superclass chain up, stopping when the method is found:
The receiver of the "class_method" call is Derived. So follow the chain right to Derived's class object, which is its eigenclass (#Derived).
Derived does not define the method, so Ruby follows the chain up the chain to #Derived's superclass, which is #Base.
The method is found there, so Ruby dispatches the message to #Base.class_method
You don't think I knew all this stuff off the top of my head, did you? Here's where my brain got all this meta juju: Metaprogramming Ruby.
Part 2. How to make an "eigenclass" (aka "singleton class") come out of hiding
class Object
def eigenclass
class << self
self
end
end
end
This method will return the eigenclass of any object. Now, what about classes? Those are objects, too.
p Derived.eigenclass # => #<Class:Derived>
p Derived.eigenclass.superclass # => #<Class:Base>
p Base.eigenclass # => #<Class:Base>
Note: Above is from Ruby1.9. When run under Ruby 1.8, you get a surprise:
p Derived.eigenclass.superclass # => #<Class:Class>

To clarify and correct what i wrote in the comments regarding the way Ruby hides/exposes eigenclasses, here is the situation:
Ruby 1.8:
(1) The Object#class method always returns the first real (non eigenclass or iclass) superclass of the actual class of an object.
e.g
o = Object.new
class << o; end
o.class #=> returns Object, even though the _actual_ class is the eigenclass of o
In other words, the Object#class method will never return an eigenclass, it passes over them
and instead returns the first 'real' class it finds in the inheritance hierarchy.
(2) The Class#superclass method has two cases. If the receiver is not an eigenclass then it simply returns the superclass. However, if the receiver is an eigenclass then this method returns the actual (i.e not necessarily real) class of the receiver.
# case where receiver is a normal class (i.e not an eigenclass)
Module.superclass #=> Object (behaves as expected)
# case where receiver is an eigenclass
class << Module; superclass; end #=> returns Class, this is NOT the superclass
From above, Class#superclass behaves as expected in the case of a normal class, but for the eigenclass example it states the superclass of the eigenclass of Module is Class which is not true. From this diagram http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/ we know that the superclass of the eigenclass of Module is actually the eigenclass of Object. I am unsure why Ruby 1.8 has this strange behaviour.
Ruby 1.9:
(1) The Object#class method behaves identically to the 1.8 version.
(2) The Class#superclass method no longer has two cases, it now treats eigenclasses the same way it treats normal classes and returns the actual superclass as expected.
e.g
class << Module; superclass; end #=> #<Class:Object>

This diagram explains the relationship: http://banisterfiend.wordpress.com/2008/11/25/a-complete-ruby-class-diagram/
Also, here are some other posts that explain more the intricacies of eigenclasses:
http://www.klankboomklang.com/2007/10/05/the-metaclass/
http://www.klankboomklang.com/2007/09/21/the-singleton-class/
And here's a fairly hard-going one that explains more than you'd probably like to know:
http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/

Related

Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant

From Wikibooks' Ruby Programming/Overview:
When I said that every Ruby object has a class, I lied. The truth is, every object has two classes: a “regular” class and a singleton class. An object’s singleton class is a nameless class whose only instance is that object. Every object has its very own singleton class, created automatically along with the object. Singleton classes inherit from their object’s regular class and are initially empty, but you can open them up and add methods to them, which can then be called on the lone object belonging to them. This is Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant
The above passage says that Ruby's secret trick to avoid class methods. I don't understand what the author means here. Where is Ruby stopping us to avoid class methods? for an example, look at the example shown below
class Raj
def self.hi
puts 'Hi'
end
def hello
puts 'hello'
end
end
object=Raj.new
object.hello
Raj.hi
As you can see in the preceding example, the class methods can still be created.
yes?
I understand that there are no true class methods in Ruby; instead, they are methods that are created for the Raj object.
But, in any case, it's allowing me to create the method 'hi,' right?
So, what does it mean when it says, 'This is Ruby's secret trick for avoiding "class methods" and keeping its type system simple and elegant'?
I understand that there are no true class methods in Ruby; instead, they are methods that are created for the Raj object.
That's exactly it, though.
def self.hi
puts 'Hi'
end
This is not a class method or static method. Those don't exist in Ruby. That's the whole point. Your class Raj defines an object of type Class. We can see its type with the #class function.
> Raj.class
=> Class
We can also see its ancestors.
> Raj.class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
Class inherits from Module, since (for the most part) classes can do everything modules can. Module, in turn, inherits from Object, which has some modules of its own mixed in (PP:ObjectMixin is for pretty-printing, and Kernel gets you the nice helpers like puts) and eventually inherits from the root class BasicObject.
But this isn't the whole story, for Raj has its own class as well: its singleton class. We can see the full story by calling #singleton_class instead of #class.
> Raj.singleton_class.ancestors
=>
[#<Class:Raj>,
#<Class:Object>,
#<Class:BasicObject>,
Class,
Module,
Object,
PP::ObjectMixin,
Kernel,
BasicObject]
Now there's a lot more going on. Raj is an instance of the singleton class of Raj, which inherits from the singleton class of Object, which in turn inherits from the singleton class of BasicObject, which inherits from Class and all of the stuff we saw before.
So when you define a method on the class Raj, you're defining it (as an instance method) on the singleton class #<Class:Raj>. And that class (currently) has one instance: Raj.
By the way, it's also useful to know that the term "singleton class" is a bit of a lie. As you can see, the class is very much not a singleton in general. For instance, the singleton class of Object, called #<Class:Object> above, actually has several instances: Object, Raj, String, and most Ruby classes. Personally, I prefer to call them eigenclasses for that reason, but "singleton class" is the official (and more well-known) term.
The author is talking about the singleton class in this sentence, there is a really nice article to deep dive into ruby singleton class: https://medium.com/#leo_hetsch/demystifying-singleton-classes-in-ruby-caf3fa4c9d91
Here is a nice example extracted from this article:
class Vehicle
def initialize(kms)
#kms = kms
end
def drive
puts "let's go!"
end
end
car = Vehicle.new(1000)
bus = Vehicle.new(3000)
def car.drive
print "I'm driving a car! "
super
end
car.drive # "I'm driving a car! let's go!"
bus.drive # "let's go!"
As you can see, here the #drive method has been overridden but only for the car object, the bus object is still using the #drive method defined in the Vehicle class.
This new method is defined on the singleton class (or shadow class) of the object, this is allowing you to define new methods on the fly on an object without polluting all the objects of this class.
This means that Ruby doesn't implement class methods.
Indeed, the Ruby OBJECT Model, allows you to "emulate" the definition of class methods by defining instance methods on the Eigenclass:
class Greeting
def self.hello
'hello world!'
end
def self.eigenclass
class << self
self
end
end
end
Greeting.eigenclass # => #<Class:Greeting>
Greeting.eigenclass.name # => nil
Greeting.singleton_methods # => [:hello, :eigenclass]
Greeting.eigenclass.instance_methods(false) # => [:hello, :eigenclass]
First, we define a Greeting.eigenclass method. This method returns self in the context of the eigenclass — by using the class << self ... end syntax. In this case, self contains an unnamed instance of the class Class (a.k.a an anonymous class). This anonymous class keeps track of the class to which it is attached — the Greeting class in our case.
Then, we can see that the singleton methods of the Greeting class are the instance methods of the Greeting eigenclass.
Feel free to have a look to this very detailed article to learn more about this concept.
To illustrate #Sébastien P.'s answer:
dice = [1,2,3,4,5,6] #an ordinary array instance
def dice.throw #now it has an extra
sample
end
p dice.throw #=>3

Why can some classes and/or methods be called without instances of their parent class?

I'm near the finish of the Ruby track in Code Academy, and I'm curious about a peculiar thing: I was under the impression that a class is a repository of constants, methods, etc... and that in order to access most of them, you would first need to create an instance of that class or in some cases the methods of themselves can be invoked (as in they are all technically part of the global object). And then I saw something like this:
#Worked
Time.now
I understood as this as the method [now] of instance of class [Time] being invoked. I then tried to invoke the method on its own:
#Failed
now
and that failed, and I assumed that while a method can be created in the general scope [as part of the global object], if it relies on initialized variables of "parent" class, it cannot be called on its own, because it would not know which object to search for those initialized variables. Following that I created a test class:
class Clock
def initialize
#hours = 1
#minutes = 30
end
def showTime
puts "The time is: #{#hours}:#{#minutes}"
end
end
#this worked
watch = Clock.new
watch.showTime
#this failed
showTime
I then just created a basic method (assuming it's in the global level)
def mymethod
puts "The mighty METHOD!"
end
#Works
mymethod
and calling this method the way I did, without referencing the global object worked. So... the questions I have are as follows:
How can [Time.now] be called in this fashion? Shouldn't there be an instance of Time first created?
Why can't I call the method [now] on its own? Am I right that it relies on resources that it cannot find when called this way?
Why could I not call the method showTime on its own? But if I define any method on the "global" level I can access it without referencing the global object
First of all, your intuition is correct.
Every methods must be an instance method of some receiver.
Global methods are defined as private instance methods on Object class and hence seem to be globally available. Why? From any context Object is always in the class hierarchy of self and hence private methods on Object are always callable without receiver.
def fuuuuuuuuuuun
end
Object.private_methods.include?(:fuuuuuuuuuuun)
# => true
Class methods are defined as instance methods on the "singleton class" of their class instance. Every object in Ruby has two classes, a "singleton class" with instance methods just for that one single object and a "normal class" with method for all objects of that class. Classes are no different, they are objects of the Class class and may have singleton methods.
class A
class << self # the singleton class
def example
end
end
end
A.singleton_class.instance_methods.include?(:example)
# => true
Alternative ways of defining class methods are
class A
def self.example
end
end
# or
def A.example
end
Fun fact, you can define singleton methods on any object (not just on class objects) using the same syntax def (receiver).(method name) as follows
str = "hello"
def str.square_size
size * size
end
str.square_size
# => 25
"any other string".square_size
# => raises NoMethodError
Some programming language history — Singleton classes are taken from the Smalltalk language where they are called "metaclasses". Basically all object-oriented features in Ruby (as well as the functional-style enumerators on Enumerable) are taken from the Smalltalk language. Smalltalk was an early class-based object-oriented language created in the 70ies. It was also the language that invented graphical user interfaces like overlapping windows and menus et cetera. If you love Ruby maybe also take a look at Smalltalk, you might fall in love yet again.
This is known as a class method. If CodeAcademy didn't cover it, that's a shame. Here's some examples:
# basic way
class Foo
def self.bar; :ok; end
end
Foo.bar # => :ok
# alternate syntax
class Foo
class << self
def bar; :ok; end
end
end
# alternate syntax, if Foo class already exists
def Foo.bar; :ok; end
# alternate approach if Foo class already exists
Foo.class_exec do
def bar; :ok; end
end
# to define a class method on an anonymous 'class' for a single instance
# you won't need to use this often
Foo.new.singleton_class.class_exec do
def bar; :ok; end
end
# to define a class method on an instance's actual class
Foo.new.class.class_exec do
def bar; :ok; end
end
Another way to get class methods is to extend a module.
module FooMethods
def bar; :ok; end
end
module Foo
extend FooMethods
end
Foo.bar # => :ok
Note that with Modules, the methods are always defined as instance methods. This way they can be either extended into class scope or included into instance scope. Modules can also have class methods, using the exact same syntax / examples as shown above with classes. However there's not such as easy to load a module's class methods via include or extend.
How can [Time.now] be called in this fashion? Shouldn't there be an
instance of Time first created?
The Time.now method is a class method, not an instance method and therefore can be called directly on the Time class rather than an instance of it Time.new
Class methods are defined on the class themselves using the self keyword:
class Time
def self.now
# code
end
end
Time.now # works
Why can't I call the method [now] on its own? Am I right that it
relies on resources that it cannot find when called this way?
When you call a method "on its own" you're actually implicitly calling it on self:
self.now
The above is the same as just doing:
now
Why could I not call the method showTime on its own? But if I define
any method on the "global" level I can access it without referencing
the global object
You defined the showTime method on a specific class so you have to send that method to that class. When you define a method in the "global" scope you're implicitly defining it on self and the subsequent call to mymethod is actually self.mymethod so it will work.
Time.now is a class method.
To define a class method, you need to define the method with self. : def self.method_name
class Clock
#hours = 1
#minutes = 30
def self.showTime
puts "The time is: #{#hours}:#{#minutes}"
end
end
Clock.showTime
#=> The time is: 1:30
If you want to call now on its own, you can do so inside Time class :
class Time
puts now
#=> 2017-01-19 22:17:29 +0100
end

How does 'defining a method' work semantically?

Background:
Here is what I understand about the object model (relative to my question below):
self always references the receiver in the current stack frame.
When you are in the top level and you say def someMethod the implicit receiver is self and you are creating a method which sits in the anonymous class associated with self. This anonymous class happens to sit just under Object (self is an instance of the Object class) so when you call someMethod, Ruby "takes a step to the right", and it lands in the anonymous class, thus finding and invoking your method.
This is similar to what goes on when you define methods inside of class definitions. If, when inside a class definition, you say: def self.classMethod you are creating a method in an anonymous class that sits just underneath the Class class. Methods of this class, existing "to the right" of the class currently being defined will not be visible to instances of the new class.
My Question:
How does "defining a method in a class" happen in the first place? (semantically)
Class objects aren't supposed to be different from normal objects, right?
From what I understand about message handling, Class objects have a table as a part of their state, presumable meaning it is an instance variable, that has the names of all of its instance methods. This is how the method look up works. (If Ruby doesn't find it , it goes up one and again, presumably the directions to the next link up the chain are a part of the state of the current Class object.)
Since Ruby doesn't really care about object type, I presume it doesn't care that it's looking in Class objects specifically when doing method look up. Rather, it's just following references and looking for bits of state with certain names. So, could I create my own "class objects" without using the class keyword that don't inherit from the Class class?
If that question doesn't make any sense, then I apologize. I just want to know what happens when the interpreter encounters the def keyword.
When you write 'def something' in ruby you are adding a method to a module. Sometimes that module is a 'class' (a type of module). It all depends on what 'self' is at the time:
class Foo
# right now self is 'Foo'
class << self
# right now self is 'Class:Foo'
end
def self.bar
# right now self is 'Foo'
end
end
def Foo.buz
# right now self is 'Foo'
end
obj = Foo.new
def obj.baz
# right now self is 'Foo:0x007fe8a632fa78' (an instance)
end
A class is just a type of module. Subclassing is one way of creating a pointer from One module up to another:
class Foo
end
class Bar < Foo
end
> Bar.ancestors
=> [Bar, Foo, Object, Kernel, BasicObject]
Another way is including mixins:
module Mixin
end
class Foo
include Mixin
end
> Foo.ancestors
=> [Foo, Mixin, Object, Kernel, BasicObject]
Method dispatch works on what exists in the inheritance chain. It's a list (not a tree) of parent modules and is ordered based on when the inheritance was created:
# bar.rb
module MixinA
def something
puts "MixinA"
super
end
end
module MixinB
def something
puts "MixinB"
end
end
class Base
def something
puts "Base"
super
end
end
class Sub < Base
include MixinB
include MixinA
def something
puts "Sub"
super
end
end
obj = Sub.new
obj.something
Run:
$ ruby bar.rb
Sub
MixinA
MixinB
Inspecting the chain:
> Sub.ancestors
=> [Sub, MixinA, MixinB, Base, Object, Kernel, BasicObject]
When a method call happens in walks this list looking for the method in question. If none of the modules in the chain have the method then the search starts over at the top but instead calls method_missing. In either case, the first resolution found wins.
Yehuda Katz wrote a good article on this stuff in 2009:
http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/

Get Ruby class name without class method

How can I get the class name of an instance of BasicObject in Ruby? For example, say I have this:
class MyObjectSystem < BasicObject
end
puts MyObjectSystem.new.class
How can I make this code succeed?
EDIT: I've found that Object's instance method class is defined as return rb_class_real(CLASS_OF(obj));. Any way to use this from Ruby?
I spent some time playing around with irb and came up with this:
class BasicObject
def class
klass = class << self; self; end # get the object's singleton class
klass.superclass # the superclass of an object's singleton class is that object's class
end
end
That will give any object that inherits from BasicObject a #class method that you can call.
Edit
Further explanation as requested in the comments:
Say you have object obj that is an instance of class Foo. obj gets its instance methods from those that are defined within the class Foo, in addition to the methods defined in Foo's parent class and so on up the inheritance chain. Ruby lets you define methods directly on an object that are only accessible to that particular object like this
obj = Foo.new
def obj.hello
puts "hello"
end
obj.hello #=> hello
other_obj = Foo.new
other_obj.hello #=> Method missing error
The reason you can do this is because every object has something called a singleton class (or sometimes call an eigenclass) that you are actually defining the method on. This singleton class actually exists in the inheritance chain of the object directly beneath the object's actual class. That makes the object's actual class, Foo in this example, the superclass of the object's singleton class.
The class << self line you see in the answer is a special syntax for entering the scope of an object's singleton class. So in the example above, you could also define a method in an object's singleton class like this
class << obj
def goodbye
puts "goodbye"
end
end
obj.goodbye #=> goodbye
So the line class << self; self; end is opening the object's singleton class (whatever object is currently self) and then returning self (self has now become the singleton class), which can then be assigned to a variable to do what you wish with.
I would recommend reading Metaprogramming Ruby if you want a better explanation of all this. It definitely gives you a much better understanding of the Ruby object model as a whole.
I have to leave in a few minutes so I can't test it myself, but it seems like you could make a separate module that uses ffi to call rb_class_real from libruby. If I had more time I would test it first, but nobody else has answered yet and I don't want you leave you totally out in the cold.
Based on Jeff Smith's answer, you can do this without modifying BasicObject:
class << object; self; end.superclass
where object is an instance of an object whose class you want, i.e.,
irb(main):001:0> object = BasicObject.new
(Object doesn't support #inspect)
=>
irb(main):002:0> class << object; self; end.superclass
=> BasicObject

Anonymous class

Here is an example:
class A
class << self
p superclass
end
end
a = A.new
class << a
p superclass
end
This code print:
#<Class:Object>
A
Why instead of
Class
A
print line
#<Class:Object>
A
?
For an anonymous class
class << self
p superclass
end
superclass is Class
I am not 100% sure if I understand the question correctly. Please rephrase it or provide more details in case I misunderstood it.
A call to superclass returns an object, which in this case is Class. In Ruby everything is an object. To my knowledge this is correct behaviour.
If you want to see the name of the class only, call p superclass.name.
Edit A call to superclass can return nil. When you do: class << a, you are extending a with new methods (take a look at this reading about classes, objects and modules). Since a is an Object (an instance of class A), it has no superclass - Object is the top of hierarchy tree. Class A has a superclass (class named Class), but not the instance of A it.

Resources