From: "trans. (T. Onoma)" Date: 2004-11-15T22:44:18+09:00 Subject: Re: OpenStruct#update ? On Monday 15 November 2004 07:38 am, Robert Klemme wrote: | "Florian Gross" schrieb im Newsbeitrag | news:2vrj8eF2oj365U1@uni-berlin.de... | | > trans. (T. Onoma) wrote: | > > Sure. Okay first, basically what I was doing, given object o and data | | in hash | | > > h: | > > | > > h.each do |k,v| | > > o.instance_variable_set("@#{k}", v) | > > o.instance_eval <<-EOS | > > def #{k}; @#{k}; end | > > def #{k}=(x); @#{k}=x; end | > > EOS | > > end | > | > h.each do |k,v| | > class << o; self; end.send(:attr_accessor, k) | > o.k = v | > end | | Are you sure, this works? IMHO this is more efficient: Actually the example is pulled inside out from the real method I use which is a method of class Object (where it does work). So no the above probably doesn't work as give --but was just intended to give approx. notion of what I'm doing. | class << o; self; end.send(:attr_accessor, *h.keys) | h.each do |k,v| | o.send("#{k}=", v) | end | | But it would be even better to check for existing methods in order to not | overwrite existing methods: | | cl = class << o; self; end | im = cl.instance_methods | h.each do |k,v| | cl.send(:attr_reader, k) unless im.include?(k.to_s) | cl.send(:attr_writer, k) unless im.include?("#{k}=") | o.send("#{k}=", v) | end I'm not sure I want that. Hmm... It's a sticky issue depending largely on the particular use case. I think it makes sense for general use, so yes --I'll add something like that, thanks. Should it raise an error instead? But in the context of an OpenStruct, no. OpenStruct focus is on data. T.