Project

General

Profile

Bug #13930

Updated by msauter (Michael Sauter) over 6 years ago

Given the following code: 

 ~~~ ruby 
 def foo 
   i = 0 
   3.times do |n| 
     begin 
       puts "a" 
       i += 1 
       next if i > 1 
       puts "b" 
     rescue => e 
       puts "rescue in foo, caught #{e}" 
     ensure 
       puts "ensure in foo, yield from foo: #{n}" 
       yield n 
     end 
   end 
 end 

 begin 
   x = 0 
   foo do |o| 
     puts o 
     x += 1 
     raise "test" if x > 1 
     puts "done yielding" 
   end 
 rescue => e 
   puts "rescue outside, caught #{e}" 
 ensure 
   puts "ensure outside" 
 end 
 ~~~ 

 The output is: 
 ~~~ 
 a 
 b 
 ensure in foo, yield from foo: 0 
 0 
 done yielding 
 a 
 ensure in foo, yield from foo: 1 
 1 
 rescue in foo, caught test 
 ensure in foo, yield from foo: 1 
 1 
 rescue outside, caught test outside 
 ensure outside 
 ~~~ 

 So the exception raised within the yielded block is caught in the rescue block above the ensure block which yielded. That sounds wrong to me. Or is it intended? The issue seems to be with the usage of next. Also, exception is caught inside AND outside ?! 

 If I change the code to this: 

 ~~~ ruby 
 def foo 
   i = 0 
   3.times do |n| 
     begin 
       puts "a" 
       i += 1 
       # next if i > 1 
       puts "b" 
     rescue => e 
       puts "rescue in foo, caught #{e}" 
     ensure 
       puts "ensure in foo, yield from foo: #{n}" 
       yield n 
     end 
   end 
 end 

 begin 
   x = 0 
   foo do |o| 
     puts o 
     x += 1 
     raise "test" if x > 1 
     puts "done yielding" 
   end 
 rescue => e 
   puts "rescue outside, caught #{e}" 
 ensure 
   puts "ensure outside" 
 end 
 ~~~ 

 Then the output is: 
 ~~~ 
 a 
 b 
 ensure in foo, yield from foo: 0 
 0 
 done yielding 
 a 
 b 
 ensure in foo, yield from foo: 1 
 1 
 rescue outside, caught test 
 ensure outside 
 ~~~ 

 I would have expected this output also when using next as above. 

Back