Hello all,

I started learning Ruby not long ago and I'd really like to understand
concepts behind it.
Poignant Guide to ruby (http://poignantguide.net/ruby/chapter-6.html)
is a very usefull book for this.
Below example is extracted from this book and some things remain quite
magical for me.

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


---------------------
class Creature
   traits :life, :strength, :charisma, :weapon
 end
---------------------


---------  generated Creature class ----------
 class Creature

   # 1. set up reader and writer methods
   attr_accessor :life, :strength, :charisma, :weapon

   # 2. add new class methods to use in creature
   def self.life( val )
     @traits ||= {}
     @traits['life'] = val
   end

   def self.strength( val )
     @traits ||= {}
     @traits['strength'] = val
   end

   def self.charisma( val )
     @traits ||= {}
     @traits['charisma'] = val
   end

   def self.weapon( val )
     @traits ||= {}
     @traits['weapon'] = val
   end

   # 3. initialize sets the default points for
   #    each trait
   def initialize
     self.class.traits.each do |k,v|
       instance_variable_set("@#{k}", v)
     end
   end

 end
----------------------------------

The thing I do not really understand is the instance_eval and
class_eval in the self.traits method.
It seems that metaclass.instance_eval define_method create a Class
method in the Creature class. Creating a method in the singleton class
of a Class class always define a Class method? can the Singleton class
can also be used to create an instance method of Creature ? Is the way
presented in this example is what is commonly done to dynamically
define Class and instance method of a Class or are there any other
possible syntaxes ?

The self.traits method also define accessors methods: attr_accessor
*arr, how come this is not done within a define_method statement?

Well.... I hope I am not getting to confusing....
I would really appreciate your help as I'd really like to understand
how that's working.
I have already read several article on metaprogramming but some things
remain quite obscure to me :-)

Thanks a lot,
Luc