From: Ben Giddings Date: 2004-06-26T09:22:57+09:00 Subject: "attr" like functions 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