From: ptkwt@... (Phil Tomson) Date: 2005-03-29T03:09:56+09:00 Subject: Re: User defined loops (applicable to DSLs) In article , Relm wrote: >On Mon, 28 Mar 2005, Phil Tomson wrote: > >> Actually, I figured out a way to make it much more natural: >> >> Change Whiler to accept an optional condition in it's constructor like >> so: >> >> class Whiler >> def initialize(cond=nil) >> @ret = nil >> @cond = cond >> end >> def while(cond=@cond) >> break @ret unless cond >> @ret = yield >> retry >> end >> end >> >> >> Define the my_while top-level method like so: >> >> def my_while(cond,&block) >> Whiler.new(cond).method(:while).call(&block) >> end > >This new my_while doesn't seem to return the last block. The following >snippet outputs nil values instead of "outer" and "inner": > > i = 0 > x = nil > y = nil > > x = my_while(i<10) do > j=0 > y = my_while(j<10) do > j+=1 > "inner" > end > i+=1 > "outer" > end > > puts x > puts y > Hmmm... I'm seeing the same thing you are, but I'm not sure why. Anyone got any ideas? >This makes your original my_while thread-safe. It was already safe for >nesting. > > def my_while(cond) > @ret ||= {} > key = Thread.current > return @ret.delete(key) unless cond > @ret[key] = yield > retry > end > That'll work. Phil