I came across an interesting problem today.  Say you wanted to have an 
object where all the instance variables have an associated description. 
  You also wanted to have a 'pretty_print' method, that would print out 
the description of the variable, along with the value.  Here's how the 
ideal code would look:

class Coordinate < DescribedObject
   attr_with_desc :x, "X Coordinate"
   attr_with_desc :y, "Y Coordinate"
   attr_with_desc :z, "Z Coordinate"
end

coord = Coordinate.new
coord.x = 1
coord.y = 2
coord.z = 3

coord.pretty_print
X Coordinate: 1
Y Coordinate: 2
Z Coordinate: 3


I managed to get that kind of behaviour with this code:


class Module
   def attr_with_desc(sym, desc="Instance var")
     attr_accessor sym
     eval_str = "@@desc[\"@#{sym.id2name}\"] = \"#{desc.to_s}\""
     puts(eval_str)
     module_eval(eval_str)
   end
end

class DescribedObject
   @@desc = Hash.new

   def pretty_print
     instance_variables.each {
       |var|
       if @@desc.has_key?(var)
         puts "#{@@desc[var]}: #{eval(var)}"
       else
         puts "Instance var #{var}: #{eval(var)}"
       end
     }
   end
end

class Coordinate < DescribedObject
   attr_with_desc :x, "X Coord"
   attr_with_desc :y, "Y Coord"
   attr_with_desc :z, "Z Coord"
end


But there are still a couple of things that I don't think are ideal 
about this, and wonder if it is possible to fix:

1) Is there a way to add the 'attr_with_desc' method without having to 
modify the Module class?  I'd like to keep it pristine, if possible.

2) Both Module and DescribedObject have to know that the variable is 
named '@@desc', so if they get out of sync, then that could be bad.  Is 
there a way of grouping all the code into one class/module?

Ben