From: Trans Date: 2007-11-28T20:48:20+09:00 Subject: Re: define_method and instance variable maddness On Nov 28, 4:28 am, Sharon Phillips wrote: > Hi, > > This problem has been driving me nuts, so I've finally given in and > decided to ask for help. > > I'm just cutting my teeth on metaprogramming but am stuck referencing > instance variables within define_method > > Here's the code snippet in question. It works, but is extremely ugly > with its constant usage of instance_variable_get and set. > > child_list_name= ('@'+(child.to_s)+"_list") > self_method= (self.name.downcase+'=').to_sym > method_name= ('add_'+child.to_s).to_sym > > define_method method_name do |new_child| > instance_variable_set(child_list_name, []) if > instance_variable_get(child_list_name).nil? > unless instance_variable_get(child_list_name).include? new_child > instance_variable_set(child_list_name, > (instance_variable_get(child_list_name) << new_child)) > if new_child.respond_to? self_method > new_child.send self_method, self > end > end > end > > This is what I'd really like the new method to look like (for > child== :personnel): > > def add_personnel (new_personnel) > unless (@personnel_list||=[]).include? new_personnel > @personnel_list << new_personnel > self_method= (self.name.downcase+'=').to_sym > if new_personnel.respond_to? self_method > new_personnel.send self_method, self > end > end > end > > Any help appreciated. I make two possible suggestions. Create yourself something shorter than instance_variable_set/get. Eg. def __iv(name,value=Exception) if value==Exception instance_variable_get("@#{name}") else instance_variable_set("@#{name}", value) end end That will make it easier to read: define_method method_name do |new_child| __iv(child_list_name, []) if __iv(child_list_name).nil? unless __iv(child_list_name).include? new_child __iv(child_list_name, (__iv(child_list_name) << new_child)) if new_child.respond_to? self_method new_child.send self_method, self end end end Secondly, use eval if it makes the code easier to maintain. T.