From: Robert Klemme Date: 2008-11-07T08:03:10+09:00 Subject: Re: Creating object from hash On 06.11.2008 21:44, Davi Barbosa wrote: > I'm creating an object from a hash using this: > > class Computer > def initialize(hash) > hash.each do |k,v| > instance_variable_set("@#{k}", v) ## create and initialize an > instance variable for this key/value pair > instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect} > ; end } > end > end > end > > This works fine except if I need to define a method with the same name > of a key (if I need an complicated getter/setter for example). So I > added a test to attr_reader line: > instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect} ; end > } if !instance_eval %Q{defined? #{k}} > > As an Object, some methods are defined (like "id"). So "pc = > Computer.new({'id' > 1})" does not create the reader for @id and "pc.id" > calls some unwanted method. > > If I just add "attr_reader :id" everything works. Can I do it directly, > without adding attr_reader (or attr_accessor) every time that I get an > error? You can make your life easier with Struct: irb(main):001:0> Comp = Struct.new :id do irb(main):002:1* def initialize(h) irb(main):003:2> members.each {|m| self[m] = h[m] || h[m.to_sym]} irb(main):004:2> end irb(main):005:1> end => Comp irb(main):006:0> c = Comp.new(:id=>133) => # irb(main):007:0> d = Comp.new("id"=>133) => # irb(main):008:0> Kind regards robert