Eval

J

John

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

z.add_attribute( resultset[0], resultset[1] )
puts z.fruit #banana
 
D

Dan Doel

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
end

obj = Method1.new

obj.add_attr("foo", "bar")

obj2 = Method2.new
obj2.add_attr("baz", "frob")

p obj.foo

p obj2.baz
p obj2.any_undefined_method_name
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top