From: Brian Mitchell Date: 2007-12-08T02:37:57+09:00 Subject: Re: Clarification of retry change On Dec 7, 2007 12:48 AM, Charles Oliver Nutter wrote: > SASADA Koichi wrote: > > And more. > > > > begin > > # body > > rescue > > 1.times{ > > retry # (4) > > } > > end > > > > begin > > # body > > rescue > > 1.times{ > > eval("retry") # (5) > > } > > end > > > > > > What should be done with (4) and (5)? > > I would think they should be "rescue retries" in both cases, and bubble > out to the rescue block, or they should also be disallowed. I don't know > which would be more consistent, but I can see valid uses for the block form: > > begin > # body > rescue > some_array.each {|value| retry if value.is_not_something?} > end > > Perhaps eval should stop retries in most cases? eval clouds expected > behavior for me. > In these cases I could see it being confusing if retry didn't work in the block but as a lexically dependent expression on rescue. This is currently against the 1.8 behavior where the retry only refers to the "some_array.each {|value| retry ...}" part. An example test for this difference: s = ['R', 'u', 'b', 'y', "\n"] begin print s.shift raise rescue s.any? {retry} end This would work only if retry was allowed to function in blocks (or other nested scopes being run) on behalf of the rescue. I would imagine that a proc could be passed in from the outside for that as well, which might be a case we either refuse to support or check dynamically for the enclosing rescue upon execution: utility_proc = lambda {|x| x.any? {retry}} Would that proc be valid when used above in rescue as "utility_proc[s]"? One more ugly case is when we extract the block from the valid scope: invalid_escape = begin raise rescue lambda {retry} end We now have a Proc object, which is ok, but invocation here should lead to an error unless it is put under a different rescue: begin raise rescue invalid_escape.call # Would this then work? end The same sort of examples can be done for simple method calls in place of the blocks and lambdas above. The eval case seems much more obscure. I would follow the rules given for break and next inside eval and disallow retry (I think it already works this way). To me the location/scope of the retry expression doesn't matter as much as the effect the retry has when run. Requiring retry to be _run_ in the context of a rescue node (possibly at any level above the running code) might make more sense. Brian.