Trans
11/28/2007 11:48:00 AM
On Nov 28, 4:28 am, Sharon Phillips <phillip...@yahoo.co.uk> 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.