Eval

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

I think you’d find the Struct class useful. Here’s a link to the pickax
book discussion:

http://www.learningruby.com/programmingrubybook/ref_c_struct.html

There’s also the Openstruct class, an example of which is given here:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/71380

Regards,

Mark

···

On Tuesday, September 9, 2003, at 05:26 PM, John wrote:

I am trying to create a class with attributes that are values
retrieved from a database. E.g.

[snip]

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? [snip]

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

Japanese-rubyists have you been read this news ?. I think so.

http://news.bbc.co.uk/1/hi/technology/3090918.stm

Could be a opportunity for RubyOS (Linux + Ruby ) , why not ?.

···


Enrique Meza emeza@saisamx.com