From: "Ara.T.Howard" Date: 2005-10-12T13:01:52+09:00 Subject: Re: calling blocks with arguments from other contexts On Wed, 12 Oct 2005, Martin wrote: > Now that is a super cool ruby hack. Thank you. > > I was able to mold it to the way I wanted it. Now it can temporarily define > a method, call the method with arguments and then undefine the temporary > method. I'm guessing this comes with a cost? slowness? > > class Foo > def red(&p) > @z = p > end > > def blue(y) > Foo.send(:define_method, :blue_temp, @z) > blue_temp(y) > Foo.send(:undef_method, :blue_temp) > end > > def green > puts "Yeah!" > end > end > > x = Foo.new > > x.red do |y| > green > puts y > end > > x.blue 5 fyi. i posted this code a while back, it does the above in a thread-safe way: harp:~ > cat a.rb class Object def evaluate(*a, &b) ret, sent = nil loop do m = "____evaluate____#{ Thread::current.object_id }____#{ rand 666 }____#{ rand 42 }____" klass = Class === self ? self : self::class begin klass.module_eval{ define_method m, &b } ret = send(sent = m, *a) ensure begin klass.module_eval{ remove_method m } ensure break if sent end end end ret end end class Foo attr_accessor "rb" def red &b self.rb = b end def blue y evaluate y, &rb end def green puts "green" end end foo = Foo::new foo.red do |y| green puts y end foo.blue 5 harp:~ > ruby a.rb green 5 and yes, it's probaly slow. cheers. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | Your life dwells amoung the causes of death | Like a lamp standing in a strong breeze. --Nagarjuna ===============================================================================