Hi --

On Wed, 13 Dec 2006, J2M wrote:

>
> dblack / wobblini.net wrote:
>
>> I'd have to see the current version of the code to be sure, but
>> define_method gives you a closure, so if you have a local variable
>> outside it, that variable will be captured.  Or maybe an instance
>> variable.  Can you post what you've currently got?
>
> class Foo
>    def bar(*args, &block)
>      if block_given?
>       class << block
>          @@return = {}
>          lambd.define_method(:method_missing, (m, *args, &b)
>            return @@return.merge!({ m.to_sym => args })
>          end
>        end
>        attributes = lambd.instance_eval(&block)
>      end
>      p attributes
>    end
> end

@@return is going to be a new variable each time you call bar with a
block, so it won't accumulate results from multiple calls (which I
think is what you want to do).

See if this either does what you want or suggests some possibilities:

   class Foo

     def bar(*args, &block)
       method_calls = @method_calls ||= {}
       if block
         (class << block; self; end).class_eval do
           define_method(:method_missing) do |m,*args|
             method_calls.merge!({ m.to_sym => args })
           end
         end
         attributes = block.instance_eval(&block)
         p attributes
       end
     end
   end

   x = Foo.new
   x.bar { baz(1,2,3) }
   x.bar { blah(4,5,6) }

Output:

{:baz=>[1, 2, 3]}
{:baz=>[1, 2, 3], :blah=>[4, 5, 6]}


David

-- 
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
    aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)