I am trying to create a class with attributes that are values
retrieved from a database. E.g.
class Item
attr_accessor :color
def initialize(color) @color = color
end
end
z = Item.new(“yellow”)
resultset = {“fruit” => “banana”}
I’d like to now set an accessor for z.fruit and set the value to
banana.
Is there a define_attribute method like there’s a define_method
method?
To put it succinctly, how can I create instance attributes after the
instance has already been created? Here’s my greenhorn attempt, but I
wonder if I’m hurting performance by invoking eval or if there’s a
more accepted way to do it:
def add_attribute(name, val)
instance_eval <<-EOD
def #{name}= (val)
@#{name} = val
end
def #{name}
@#{name}
end
@#{name} = "#{val}"
EOD
end
Other ways if you can’t use a struct for some reason.
Method2 not recommended (unless you check if the accessor has been
defined yourself).
Dan
class Method1
def add_attr(name, val)
class << self
self
end.class_eval { attr_accessor name }
send("#{name}=", val)
end
end
class Method2
def initialize @dict = Hash.new {nil}
end
def method_missing(sym, *args)
str = sym.to_s
/(.*)(=?)/ =~ str
if $2.empty?
@dict[$1.intern]
else
@dict[$1.intern] = args[0]
end
end
def add_attr(name, val)
@dict[name.intern] = val
end