Reputation: 11639
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
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
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