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

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


-- 
Relm