From: Christian Szegedy Date: 2002-09-05T19:46:42+09:00 Subject: Re: option remember C�dric Foll wrote: >>return in a block returns from the function containing the block. The >>return value of a block call is the value of the last statement. Just >>erase the word "return" from your block. > > > and > > >>$arg = [] >> >>def remember(func) >> Proc.new { |n| $arg[n] ||= method(func).call(n) } >>end > > > > Ok, it work. Thanks. > > But i've still have a problem. > When the function is recursive (like fibonnacci is) it doesn't work has > expected. > Only the first value is memorized (if i call fib(10), only the value for > n=10 and not n<10). > The first call is the new function but the new function call the old one so > i'm still in O(2^n). > > What is the solution ? > > Regards > > > You can redefine the original method, (But therefore you must alias the original one, if you do it completely correctly, then you will arrive at the solution in the pickaxe book) As an illustration of the idea, see the following code snippet: -------------------------------- def f(x) puts "f(#{x}) called" if x>0 f(x-1)+1 else 0 end end def remember(func) Proc.new { |n| ($arg||={})[n] ||= method(func).call(n) } end alias old_f f $f_rem = remember :old_f def f(*x) $f_rem.call(*x) end puts(f(3)) puts(f(5)) ------------------------------------- The crux lies in the automatic (unique!!!) name generation of old_f and $f_rem, in the general case. Best Regards, Christian