On 4 Dec 2007, at 14:29, Alex Gutteridge wrote:

> On 4 Dec 2007, at 00:06, Gregory Seidman wrote:
>
>> On Mon, Dec 03, 2007 at 02:54:32PM +0900, Charles Oliver Nutter  
>> wrote:
>>> Today I was thinking about retry support in JRuby, and figured we've
>>> reached a decision point.
>> [...]
>>> The problem I've run into is that it's really cumbersome to  
>>> implement this
>>> correctly in the compiler, cumbersome enough I'm debating whether  
>>> we'll
>>> support it. There's a few reasons for this:
>>>
>>> - retry is handled using exception; so every method call that  
>>> takes a block
>>> would have to be wrapped with exception-handling for retry to work.
>>> Exception-handling is expensive, even if no exceptions are  
>>> actually raised.
>>> It would also add a significant amount of code.
>>> - there's no way to know that a method will be reevaluated by  
>>> looking at
>>> it, which makes it both dangerous and impossible to predict.
>>> - nobody understands retry, and nobody uses it.
>>
>> Okay, I disagree with that last point. Retry is very handy when
>> appropriate, and I have, indeed, used it.
>
> I'm pretty sure Charles meant that nobody uses or understands retry  
> *outside a rescue* there. Clearly it's very useful in the context of  
> a rescue.
>
>>> This also affects retry within a block
>>>
>>> def foo(a); puts 3; yield; end
>>>
>>> (print 1; self).foo((print 2; nil)) { retry }
>>>
>>> This also prints "123" repeatedly.
>
> This works for me in irb:
>
> irb(main):004:0> def foo(a); puts 3; yield; end
> => nil
> irb(main):005:0> (print 1; self).foo((print 2; nil)) { retry }
> 123
> 123
> 123
> 123
> 123
> 123
> ......Ad infinitum
>
> But not in 1.8.6:
>
> [alexg / powerbook]/Users/alexg/Desktop(27): cat retry2.rb
> def foo(a); puts 3; yield; end
>
> (print 1; self).foo((print 2; nil)) { retry }
> [alexg / powerbook]/Users/alexg/Desktop(28): ruby retry2.rb
> retry2.rb:3: private method `foo' called for main:Object  
> (NoMethodError)

Sorry, I didn't cut and paste that correctly. The real output is:

[alexg / powerbook]/Users/alexg/Desktop(33): ruby retry2.rb
retry2.rb:3: private method `foo' called for main:Object (NoMethodError)
12[alexg / powerbook]/Users/alexg/Desktop(34):

So one 'iteration' gets called, but then 'foo' somehow becomes  
undefined? Can anyone explain this behaviour?

> Though this does:
>
> [alexg / powerbook]/Users/alexg/Desktop(31): cat retry.rb
> class Foo
>  def initialize
>    print 1
>  end
>  def foo(a); puts 3; yield; end
> end
>
> Foo.new.foo((print 2; nil)) { retry }
> [alexg / powerbook]/Users/alexg/Desktop(32): ruby retry.rb
> 123
> 123
> 123
> 123
> 123
> ......Ad infinitum
>
> Color me confused, and one extra vote for removing retry outside of  
> rescue.
>
> Alex Gutteridge
>
> Bioinformatics Center
> Kyoto University
>
>
>

Alex Gutteridge

Bioinformatics Center
Kyoto University