A Beginner's Question about Metaprogramming

Hey guys, have a question about Ruby programming and found this forum
per Google.

I was recently reading chapter 6 of Why’s Poignant Guide to Ruby
(http://mislav.uniqpath.com/poignant-guide/book/chapter-6.html), when I
stumbled upon the following code that was supposed to demonstrate
metaprogramming:


The guts of life force within Dwemthy’s Array

class Creature

Get a metaclass for this class

def self.metaclass; class << self; self; end; end

Advanced metaprogramming code for nice, clean traits

def self.traits( *arr )
return @traits if arr.empty?

 # 1. Set up accessors for each variable
 attr_accessor *arr

 # 2. Add a new class method to for each trait.
 arr.each do |a|
   metaclass.instance_eval do
     define_method( a ) do |val|
       @traits ||= {}
       @traits[a] = val
     end
   end
 end

 # 3. For each monster, the `initialize' method
 #    should use the default number for each trait.
 class_eval do
   define_method( :initialize ) do
     self.class.traits.each do |k,v|
       instance_variable_set("@#{k}", v)
     end
   end
 end

end

Creature attributes are read-only

traits :life, :strength, :charisma, :weapon
end


class Dragon < Creature
life 1340 # tough scales
strength 451 # bristling veins
charisma 1020 # toothy smile
weapon 939 # fire breath
end


I don’t understand this code at all, especially the line “def
self.metaclass; class << self; self; end; end”. Where do all the names
such as metaclass.instance_eval or class_eval come from? I’m really
confused about this piece of code, and would appreciate some
explanation. Sorry if these questions are rather basic.

On Tue, Apr 10, 2012 at 6:33 PM, Phil S. [email protected]
wrote:

I don’t understand this code at all, especially the line “def
self.metaclass; class << self; self; end; end”. Where do all the names
such as metaclass.instance_eval or class_eval come from? I’m really
confused about this piece of code, and would appreciate some
explanation. Sorry if these questions are rather basic.


Posted via http://www.ruby-forum.com/.

class << self is the same as def self.method

Look at a simpler example:

#Initial class definition:

class MyClass
def hi
“hi!!!”
end
end

Reopened with metaclass self.method style:

class MyClass
def self.hello
“hello”
end
end

Reopened with metaclass class << self style:

class MyClass
class << self
def goodbye
“bye!!!”
end
end
end

MyClass.new.hi
=> “hi!!!”
MyClass.hello
=> “hello”
MyClass.goodbye
=> “bye!!!”

On Tue, Apr 10, 2012 at 7:15 PM, Phil S. [email protected]
wrote:

Thanks, but what does this whole line mean?:

def self.metaclass; class << self; self; end; end

If I am correct, this is defining a Class method named metaclass, which
has a method named self…? Please elaborate.


Posted via http://www.ruby-forum.com/.

It returns self which in this case is a singleton class called
metaclass which also is a metaclass. It would confuse me also. class
<< self is shorthand for opening up the current class. to make things
worse you can open up metaclasses inside metaclasses.

Look at my example and run these commands:

MyClass.singleton_class
MyClass.singleton_methods

Basically these are just hidden classes which can be used for
exercising the code.

If your really interested in the subject I found metaprogramming ruby
(book) to be a very interesting read.

Thanks, but what does this whole line mean?:

def self.metaclass; class << self; self; end; end

If I am correct, this is defining a Class method named metaclass, which
has a method named self…? Please elaborate.

Thanks for the help!

So if I understand this correctly, the singleton_methods are just the
class methods. Is that right?

I actually am interested in learning more about metaprogramming, but
this 300-page read seems a bit heavy for such a topic. Is the book worth
it, and is metaprogramming important enough in Ruby to justify buying
it?

Thanks again.

Phil S. wrote in post #1055921:

Thanks, but what does this whole line mean?:

def self.metaclass; class << self; self; end; end

If I am correct, this is defining a Class method named metaclass, which
has a method named self…? Please elaborate.

No, “self” is not a method, it’s a keyword, which refers to the current
object (many other languages use “this” instead).

The metaclass method returns the eigenclass (aka meta class aka
singleton class) of the Creature class. It does this by opening the
eigenclass and using the “self” keyword inside the class body. The value
of self (the eigenclass) then becomes the value of the whole class
expression.

class << self # open the eigenclass of self (self is the Creature
class)
self # in this context, self refers to the eigenclass
end # the value of this expression is the value of self

This is a pretty common trick. However, it isn’t needed any longer,
because Ruby 1.9 already has the method Object#singleton_class built-in.

In fact, you don’t even have to get the singleton class. You can simply
call Object#define_singleton_method.

Whoa, so my code is outdated?

How would [def self.metaclass; class << self; self; end; end] be
rewritten using this syntax?

Thank you so much.

Thanks, that’s quite some information to take in.

Am I correct that the code below can’t be rewritten, since it doesn’t
deal with Singletons? (taking a risky assumption here)

class_eval do
define_method( :initialize ) do
self.class.traits.each do |k,v|
instance_variable_set("@#{k}", v)
end
end
end

After all, it only deals with the instances.

Also, I’ve been really confused about the difference between classes and
objects.
I know that Objects are classes themselves, through “Object.class”,
which returns “Class”.

If “hello” is an instance and String is a class, what is an example of
an Object?

Thanks for your continued help.

Phil S. wrote in post #1055948:

Am I correct that the code below can’t be rewritten, since it doesn’t
deal with Singletons? (taking a risky assumption here)

class_eval do
define_method( :initialize ) do
self.class.traits.each do |k,v|
instance_variable_set("@#{k}", v)
end
end
end

You could leave out the “class_eval” and “define_method” and simply
write “def initialize … end” like you normally do, since this isn’t a
dynamic method definition at all:

def initialize
self.class.traits.each do |k,v|
instance_variable_set("@#{k}", v)
end
end

Also, I’ve been really confused about the difference between classes and
objects.
I know that Objects are classes themselves, through “Object.class”,
which returns “Class”.

This is a misunderstanding. Every object has a class, which defines
the methods of the object. You can interpret classes as some kind of
“construction plans” for objects.

In most object oriented languages like Java or C++., classes aren’t
objects themselves but rather some kind of special entities. This isn’t
true for Ruby. In Ruby, classes are normal objects that behave like any
other object. They can have instance variables and methods (like for
example “superclass” or “attr_accessor”).

This is actually a good thing, because it makes for a very simple and
consistent language model. Also there’s no need to introduce special
keywords for classes (like “static” in Java).

The class of every class is “Class”.

If “hello” is an instance and String is a class, what is an example of
an Object?

Both “hello” and String are objects. “hello” is an instance of the class
String, and String is an instance of the class Class.

Phil S. wrote in post #1055945:

Whoa, so my code is outdated?

Yes. The example code was obviously written for Ruby 1.8. While it still
works in 1.9, many of the boilerplate parts aren’t needed any longer.

How would [def self.metaclass; class << self; self; end; end] be
rewritten using this syntax?

You can skip this part completely and use “define_singleton_method”
instead of “define_method”:

def self.traits( *arr )
return @traits if arr.empty?

1. Set up accessors for each variable

attr_accessor *arr

2. Add a new class method to for each trait.

arr.each do |a|
define_singleton_method( a ) do |val|
@traits ||= {}
@traits[a] = val
end
end
end

However, if you want to get the eigenclass of an object, you can simply
call its “singleton_class” method:

class A; end
a = A.new
puts a.singleton_class

Just like you call the “class” method to get the class of an object.

Phil S. wrote in post #1055939:

So if I understand this correctly, the singleton_methods are just the
class methods. Is that right?

No. Singleton methods are methods that exist only for a single object.

ary = Array.new(1…3)
ary.size
=> 3
def ary.size

  • 23748236478
  • end

ary.size
=> 23748236478

I have redefined ary’s size method, however this did not change the
parent class (Array) size method. New Arrays will have the ‘default’
size method.

‘size’ is a singleton method now:

ary.singleton_methods
=> [:size]

Földes László wrote in post #1055980:

Phil S. wrote in post #1055939:

So if I understand this correctly, the singleton_methods are just the
class methods. Is that right?

No. Singleton methods are methods that exist only for a single object.

Well, the singleton methods of a class are the class methods.

Let me do one more example for the sake of simplicity and remove self
from the example and just use a string and manipulate it in main…
Feel free to at p, puts, print, or printf where desired =)

creature = “Dragon”
creature.class
creature.singleton_methods

class << creature
def spit_fire
“Hot! Hot! Hot!!!”
end
end

def creature.blow_smoke
“caugh, cancer… ouch!”
end

creature.spit_fire
creature.blow_smoke
creature.singleton_methods

~Stu

On Wed, 11 Apr 2012 19:56:27 +0900, Jan E. wrote:

No. Singleton methods are methods that exist only for a single object.

Well, the singleton methods of a class are the class methods.

Can you clarify this? In Java, class methods are declared with static.
In ruby, I believe it’s @@, but the same upshot.

There’s a distinction between class methods and methods of a Singleton,
to my understanding. Methods on a singleton are regular methods and
require the Singleton object to be instantiated, but are most definitely
not static methods. I’m not sure about Ruby, but in Java you wouldn’t
instantiate a Math object to call Math.sqrt() or whatever, that would be
nonsensical. Class methods don’t require an instance, while, to the
contrary, Singleton is an instance. Or, rather, the only instance.

From a usage standpoint, I think it’s half a dozen of one, six of
another, but they’re not the same at all.

Please correct any misunderstandings I have.

thanks,

Thufir

Jan E. wrote in post #1055982:

Földes László wrote in post #1055980:

Phil S. wrote in post #1055939:

So if I understand this correctly, the singleton_methods are just the
class methods. Is that right?

No. Singleton methods are methods that exist only for a single object.

Well, the singleton methods of a class are the class methods.

I was referring to “the singleton_methods are just the class methods”
and smelled some confusion, because instances can have singleton methods
as well. (that’s why I widened the scope to ‘objects’ as previously it
was clarified that classes and their instances are all ‘objects’)

Thanks for all the help, but there are some more question that I have:

  1. Why is it necessary to use a Singleton class in the above example at
    all?

Here’s the code where it is used:

arr.each do |a|
    metaclass.instance_eval do
        define_method( a ) do |val|
           @traits ||= {}
           @traits[a] = val
        end
    end
 end

(I know this code is outdated, I’m just trying to understand the
concepts.)
Why are the methods defined onto the Singleton class? I would rather
think that the following is correct, but for some reason it doesn’t
work:

arr.each do |a|
    class_eval do
        define_method( a ) ...

For what the code is supposed to do, this seems like the right
function… but it does not work. Why? Why was a metaclass necessary?

2… I still don’t grasp exactly what class << self means. I know that
class << ClassName would add on to the class of ClassName. Please
explain.
Thanks.

Lastly, for anybody else who is struggling with Ruby metaprogramming, I
found this article to be very useful:

On Wed, Apr 11, 2012 at 3:44 PM, Thufir [email protected] wrote:

On Wed, 11 Apr 2012 19:56:27 +0900, Jan E. wrote:

No. Singleton methods are methods that exist only for a single object.

Well, the singleton methods of a class are the class methods.

Can you clarify this? In Java, class methods are declared with static.
In ruby, I believe it’s @@, but the same upshot.

No, @@ is to define class variables, which is a quite different things
than class methods.

another, but they’re not the same at all.

Please correct any misunderstandings I have.

As Jan said, class methods are singleton methods where the object in
which they are defined is the class object. Compare:

a = []
def a.half_size
size / 2
end

This is a singleton method for that specific array object.

class A
def self.test
puts “test method”
end
end

Here, test is a singleton method for the object that is self in that
context, that turns out to be class A. Remember that in Ruby classes
are objects.

Jesus.

Phil S. wrote in post #1056788:

Thanks for all the help, but there are some more question that I have:

  1. Why is it necessary to use a Singleton class in the above example at
    all?

An object has two sources for its methods: First of all, it can use the
methods defined in its class. Those methods are shared by all
instances of the class.

However, an object can also have methods on its own, which are not
shared with the other instances. Those methods are called “singleton
methods” and are defined in the singleton class of the object (I
wouldn’t use the word “metaclass”, because it can also have a different
meaning).

The difference between normal methods and singleton methods gets a bit
tricky when dealing with classes, because now you basically have to
distinguish between three cases:

a) A class is a normal object and can use the methods defined in its
class. The class of a class is always Class. This means: The methods
defined in Class (like “attr_accessor” or “superclass”) are shared by
all classes.

b) Like any other object, a class can also have singleton methods. Those
methods only belong to the class itself and not to the other classes.

c) A class can also define methods for its instances. It this case,
the class isn’t the user but rather the provider.

Now to your example:

Where do you want the methods to go? You certainly don’t want all
classes to have a “charisma” method. Instead, you want a specific
class to have it, namely Creature. That’s why you define a singleton
method for Creature (case b).

However, letting the class set the standard values for “charisma”,
“strength” etc. doesn’t make sense if the instances of Creature don’t
use these properties. That is, you also have to define correspoding
methods for the instances of Creature (case c). This can of course be
done automatically by calling “attr_accessor”.

You may also come to the conclusion that every class should have a
“traits” method. Then you would define this method in Class (case a).

It hope this makes things a bit clearer.

Why are the methods defined onto the Singleton class? I would rather
think that the following is correct, but for some reason it doesn’t
work:

arr.each do |a|
    class_eval do
        define_method( a ) ...

For what the code is supposed to do, this seems like the right
function… but it does not work. Why? Why was a metaclass necessary?

It does work, but it’s not what you want. You don’t want to define a
method for the instances of Creature but rather for Creature itself. The
Creature class is to set the standard values for “charisma” etc.

2… I still don’t grasp exactly what class << self means. I know that
class << ClassName would add on to the class of ClassName. Please
explain

This “class << …” is simply the syntax for defining or opening the
singleton class of an object:

class << my_object

method definitions etc.

end

As you can see, it corresponds to the syntax of defining or opening a
“normal” class:

class MyClass

method definitions etc.

end

Well, and if you want to open/define the singleton class for “self”,
then you write

class << self

end

Where do you want the methods to go? You certainly don’t want all
classes to have a “charisma” method. Instead, you want a specific
class to have it, namely Creature. That’s why you define a singleton
method for Creature (case b).

But when I say
class MyClass
def self.hello
“hi”
end
end

The above is also true in this example: No other class gets the “hello”
method, and I didn’t have to use a Singleton method.

Phil S. wrote in post #1056802:

But when I say
class MyClass
def self.hello
“hi”
end
end

The above is also true in this example: No other class gets the “hello”
method, and I didn’t have to use a Singleton method.

This is a singleton method. It’s just a different syntax: Instead of
explicitly opening the singleton class of “my_object” and defining the
method “my_method” in it, you can also write

def my_object.my_method …

end

Note that this is different from a “normal” method definition:

def my_method …

end

The “def obj.method” syntax is kind of a short form. However, you cannot
use the “def” syntax for dynamic method definitions. That’s why you
either have to open the singleton class explicitly or call
Object#define_singleton_method, which is available in Ruby 1.9 (like I
suggested earlier).