Jwan622 Jwan622 - 2 months ago 12
Ruby Question

Getting access to the metaclass in Ruby

I'm trying to better understand the rules of Ruby and how to get access to the metaclass. I'm reading Yehuda Katz's article on metaprogramming and I came across this:

matz = Object.new
def matz.speak
"Place your burden to machine's shoulders"
end

matz.class #=> Object


In fact, matz's "class" is its invisible metaclass. We can even get access to the metaclass:

metaclass = class << matz; self; end
metaclass.instance_methods.grep(/speak/) #=> ["speak"]


What is going on on this line:

metaclass = class << matz; self; end


Is that the same as:

matz
self
end


?

Answer

What is going on on this line:

metaclass = class << matz; self; end  
class << foo

opens the singleton class of foo. Inside a class definition body, self is the class. The return value of a class definition body is the value of the last expression inside the class definition body.

So, we assign the value of the class definition body, which is the value of the last expression inside the class definition body, which is self, which is the class, i.e. the singleton class of matz.

In other words: we assign the singleton class of matz to the local variable metaclass.

Note that modern Ruby has the Object#singleton_class method for that purpose (added in Ruby 1.9.2, released in 2010).

Is that the same as:

matz
   self
end

Obviously not, since the former is legal syntax, and this isn't.