In article <3alo9bF6d2vo8U1 / individual.net>,
Robert Klemme <bob.news / gmx.net> wrote:
>
>
>I'm surprised about "retry", too.  His analysis sounds all very resonable - 
>only that "break" does not work for me but "return" does:
>
>>> def my_while(cond)
>>>   break unless cond
>>>   yield
>>>   retry
>>> end
>=> nil
>>> i = 0
>=> 0
>>> my_while i < 10 do
>?>   puts i
>>>   i += 1
>>> end
>0
>1
>2
>3
>4
>5
>6
>7
>8
>9
>LocalJumpError: unexpected break
>        from (irb):2:in `my_while'
>        from (irb):7
>>> def my_while(cond)
>>>   return unless cond
>>>   yield
>>>   retry
>>> end
>=> nil
>>> i = 0
>=> 0
>>> my_while i < 10 do
>?>   puts i
>>>   i += 1
>>> end

I tried to do nested my_while's using the my_while with return instead 
of break. It doesn't work; it endlessly loops.  Using break it works 
correctly:

 i=0
 my_while i<5 do
   puts "i: #{i}"
   j = 0
   my_while j<5 do
     puts "  j: #{j}"
     j+=1
   end
   i+=1
 end

prints:

i: 0
  j: 0
  j: 1
  j: 2
  j: 3
  j: 4
i: 1
  j: 0
  j: 1
  j: 2
  j: 3
  j: 4
i: 2
  j: 0
  j: 1
  j: 2
  j: 3
  j: 4
i: 3
  j: 0
  j: 1
  j: 2
  j: 3
  j: 4
i: 4
  j: 0
  j: 1
  j: 2
  j: 3
  j: 4
=> nil


Oh, and my proposed my_while that returns the last block evaluation:

  def my_while(cond)
    break @ret unless cond #NOTE: break can return a value 
    @ret = yield
    retry
  end

wouldn't work if you have nested my_while's.  You would have to create 
some kind of class that contains a while method in order for nesting 
to be handled correctly.

something like:

  class Whiler
    def initialize
      @ret = nil
    end

    def while(cond)
      break @ret unless cond
      @ret = yield
      retry
   end
  end

  outer = Whiler.new
  inner = Whiler.new

  i=0
  outer.while i<5 do
    puts "i: #{i}"
    j=0
    inner.while j<5 do
      puts "  j: #{j}"
      j+=1
    end
    i+=1
  end

perhaps a  bit cumbersome, though.  


Phil