Hello, I need to generate read and write accessors for all the keys in
an hash.
Say I have an attribute named my_attribute, I need “my_attribute” and
“my_attribute=” methods to read and write it to
@attributes[my_attribute].
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…
Thank you,
Andrea Gianarro
@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
Andrea Gianarro wrote:
Hello, I need to generate read and write accessors for all the keys in
an hash.
Wouldn’t a simpler solution be to use OpenStruct?
require ‘ostruct’
hash={“my_attribute”=>“value”}
s=OpenStruct.new(hash)
puts s.my_attribute
value
s.my_attribute=“new”
=> “new”
puts s.my_attribute
new
=> nil
And you get the freebie of creating new keys from the setter:
s.new_attribute=“better”
=> “better”
puts s.new_attribute
better
Cheers,
V.-
James C. wrote:
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
Thank you very much, that’s exactly what I did. Strange ruby behaviour
anyway.
bye,
Andrea Gianarro