On Thu, 23 Nov 2006, Victor "Zverok" Shepelev wrote:

> Now push_XXX and use_XXX work cleaner and faster, but all those initialize
> aliases (now I have 5 or 6) don't seem to be very elegant.
>
> Is there better solution?
>
> (to be clear, all those push_XXX are NOT similar - some of them push object
> to hashes, others to arrays, params count differ and so on - so, they can't
> be generated at once through metaprogramming)

i think metaprogramming is perfect: define access to the ivars (containers) to
initialize the ivar and then __redefine__ the method in-place for direct
access thereafter :

     harp:~ > cat a.rb
     class Module
       def init_attr a, &init
         ivar = "@#{ a }"
         this = self
         define_method a do
           begin
             instance_variable_set ivar, instance_eval(&init)
           ensure
             this.module_eval{ define_method(a){ instance_variable_get ivar } }
           end
         end
       end
     end

     class C
       init_attr(:list){ Array.new }
       def push(val) list.push val end
     end

     obj = C.new
     p obj.list
     obj.push 42
     p obj.list


     harp:~ > ruby a.rb
     []
     [42]


to clean it up pull 'init_attr' into it's own module and extend only those
classes that need this functionality with the module.

regards.

-a
-- 
my religion is very simple.  my religion is kindness. -- the dalai lama