On Nov 28, 2007, at 4:28 AM, Sharon Phillips wrote:
>
> 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
>


It looks like you are maintaining multiple lists but I don't
understand why you are encoding the name of the list in the method
names and in the instance variables.  Why not just use a hash
and methods that take a list name parameter?

def add(list, obj)
   unless (@lists[list]||=[]).include? obj
     @lists[list] << obj
     if obj.respond_to? :add_container
       obj.add_container(self)
     end
   end
end

Now if you really want something like 'add_personnel' it is easy:

listname='personnel'
define_method('add_#{listname}') do |obj|
   add(listname, obj)
end

The added object can derive a name directly from  
'self' (self.name.downcase)
there is no need to figure that out for the object.

Note: I didn't test this code, but I hope you get the idea.

Bottom line: use a hash and access the key/value pairs instead of
trying to construct and dereference instance variable names.

Gary Wright