James Coglan
7/23/2008 10:24:00 AM
[Note: parts of this message were removed to make it a legal post.]
>
> I tried this code in the class constructor:
>
> for a in all_attributes
> method_name = a.name
> self.class.class_eval do
> define_method method_name do
> @attributes[method_name]
> end
> define_method method_name+"=" do |val|
> @attributes[method_name] = val
> end
> end
> end
>
> It generates the method for the class, but all the methods read and
> write to the last attribute in the all_attributes list. That's
> strange...
Ah, the strange joy that is closures. Basically, those 'define_method' calls
allow the code block to retain access to whatever variables were in scope
when the methods are defined. So, when those methods actually run, the
variable 'method_name' will have the last value in the loop -- each closure
references a single variable, it does not copy its value.
You might be better off with method_missing
class Hash
def method_missing(name, value = nil)
name = name.to_s
if name =~ /=$/
self[name.sub(/=$/, '')] = value
else
return self[name]
end
end
end