Jwan622
Jwan622

Reputation: 11639

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

?

Upvotes: 2

Views: 125

Answers (2)

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369458

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.

Upvotes: 2

Aetherus
Aetherus

Reputation: 8888

class << matz; self; end is equivalent to

class << mats
  self
end

class << matz; end opens the singleton class (Ruby official name of metaclass). It is also an expression that returns the return value of the last expression that is evaluated inside it, in this case, self.

I think you are familiar with self since you are playing with metaprogramming. The self refers to the class itself when it's in the scope of a class, in your code, it refers to the singleton class.

P.S. starts from Ruby 1.9.2, there's no need to use this shovel syntax to grab a singleton class. Just obj.singleton_class.

Upvotes: 1

Related Questions