On Thu, 5 Oct 2006, Gavin Kistner wrote:

> Because I just had to solve this problem in both JavaScript and Lua, and
> because I love Ruby more than either, I thought I'd ask people here how
> they'd solve it in Ruby.
>
> The general question is: how would do you associate a few object instances
> with methods on a per-method basis?
>
> The Situation/Requirements
> --------------------------
> A class has 2 different methods.  Each method needs a couple 'scratch'
> objects to perform its calculations.  The methods call each other; they must
> not use the same scratch objects.  It is expensive to instantiate a scratch
> object.  It's not expensive to initialize an existing scratch object with
> data.  We like OOP coding, and want to call these as methods of a receiver.
>
> Wasteful Example:
> class Foo
>  def c1
>    tmp1 = ExpensiveObject.new
>    tmp2 = ExpensiveObject.new
>    # stuff involving tmp1/tmp2
>    result = tmp1 + tmp2 + c2
>  end
>  def c2
>    tmp1 = ExpensiveObject.new
>    tmp2 = ExpensiveObject.new
>    # stuff involving tmp1/tmp2
>    result = tmp1 + tmp2
>  end
> end
>
>
> The Solution We'll Ignore
> --------------------------
> We *could* create a distinct instance variable for each needed variable.
> I personally don't like the weird coupling this creates, though. So I'm
> ignoring it.
>
> class Foo
>  def initialize
>    @tmp1 = ExpensiveObject.new
>    @tmp2 = ExpensiveObject.new
>    @tmp3 = ExpensiveObject.new
>    @tmp4 = ExpensiveObject.new
>  end
>  def c1
>    tmp1, tmp2 = @tmp1, @tmp2
>    #...
>  end
>  def c2
>    tmp1, tmp2 = @tmp3, @tmp4
>    #...
>  end
> end


what's wrong with the simple solution:

   class Foo
     METHOD_DATA = {
       'c1' => {
         'tmp1' => ExpensiveObject.new,
         'tmp2' => ExpensiveObject.new,
       },

       'c2' => {
         'tmp1' => ExpensiveObject.new,
         'tmp2' => ExpensiveObject.new,
       },
     }

    def mdata m, key
      METHOD_DATA[m.to_s][key.to_s]
    end

    def c1
      tmp1, tmp2 = mdata('c1', 'tmp1'), mdata('c1', 'tmp2')
      result = tmp1 + tmp2 + c2
    end

    def c2
      tmp1, tmp2 = mdata('c2', 'tmp1'), mdata('c2', 'tmp2')
      result = tmp1 + tmp2
    end
   end

you can make it lazy using lambda if you want...

??

cheers.


-a
-- 
in order to be effective truth must penetrate like an arrow - and that is
likely to hurt. -- wei wu wei