From: Alex Gutteridge Date: 2007-12-04T14:29:26+09:00 Subject: Re: Everyone's favorite flow control: retry 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) 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