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.

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

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 6:33 PM, Phil Stone <lists@ruby-forum.com> 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/.

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.

···

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

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.

···

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

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.

···

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

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:

···

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

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.

···

--
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.

···

On Tue, Apr 10, 2012 at 7:15 PM, Phil Stone <lists@ruby-forum.com> 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/\.

Phil Stone 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.

···

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

Phil Stone 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
###

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

Phil Stone 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").

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.

···

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

Phil Stone 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:

ary.singleton_methods

=> [:size]

···

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

Phil Stone 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

···

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

Phil Stone 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

It's 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 Module#define_singleton_method, which
is available in Ruby 1.9 (like I suggested earlier).

···

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

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

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

Phil Stone 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.

···

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

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

···

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.

Jan E. wrote in post #1055982:

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

Phil Stone 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')

···

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

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.

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.

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.

···

On Wed, Apr 11, 2012 at 3:44 PM, Thufir <hawat.thufir@gmail.com> wrote:

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