Martin DeMello wrote:
puts j
j+=1
end
puts "after loop, j = #{j}"
I’d have expected repeat (j >= 10) to pass “false” into the method,
which would then yield repeatedly to the do/end block, never seeing
the (condition) part again.
retry actually reevaluates the method invocation. If you use
set_trace_func you’ll see something like this with the attached script:
[“line”, “/c/temp/ruby/retry.rb”, 8, nil, #Binding:0x100f63e8, false]
[“line”, “/c/temp/ruby/retry.rb”, 9, nil, #Binding:0x100f63a0, false]
[“c-call”, “/c/temp/ruby/retry.rb”, 9, :>=, #Binding:0x100f6250,
Fixnum]
[“c-return”, “/c/temp/ruby/retry.rb”, 9, :>=, #Binding:0x100f6130,
Fixnum]
[“call”, “/c/temp/ruby/retry.rb”, 2, :repeat, #Binding:0x100f5f08,
Object]
[“line”, “/c/temp/ruby/retry.rb”, 3, :repeat, #Binding:0x100f5ec0,
Object]
[“c-call”, “/c/temp/ruby/retry.rb”, 3, :to_s, nil, FalseClass]
[“c-return”, “/c/temp/ruby/retry.rb”, 3, :to_s, nil, FalseClass]
[“c-call”, “/c/temp/ruby/retry.rb”, 3, :puts, #Binding:0x100f5b30,
Kernel]
[“c-call”, “/c/temp/ruby/retry.rb”, 3, :write, #Binding:0x100f5a10,
IO]
condition: false[“c-return”, “/c/temp/ruby/retry.rb”, 3, :write,
#Binding:0x100f58d8, IO]
[“c-call”, “/c/temp/ruby/retry.rb”, 3, :write, #Binding:0x100f57a0,
IO]
[“c-return”, “/c/temp/ruby/retry.rb”, 3, :write, #Binding:0x100f5680,
IO]
[“c-return”, “/c/temp/ruby/retry.rb”, 3, :puts, #Binding:0x100f5560,
Kernel]
[“line”, “/c/temp/ruby/retry.rb”, 4, :repeat, #Binding:0x100f5440,
Object]
[“line”, “/c/temp/ruby/retry.rb”, 10, nil, #Binding:0x100f5230, false]
[“c-call”, “/c/temp/ruby/retry.rb”, 10, :puts, #Binding:0x100f51e8,
Kernel]
[“c-call”, “/c/temp/ruby/retry.rb”, 10, :to_s, #Binding:0x100f50c8,
Fixnum]
[“c-return”, “/c/temp/ruby/retry.rb”, 10, :to_s, #Binding:0x100f4eb8,
Fixnum]
[“c-call”, “/c/temp/ruby/retry.rb”, 10, :write, #Binding:0x100f4e70,
IO]
0[“c-return”, “/c/temp/ruby/retry.rb”, 10, :write,
#Binding:0x100f4d50,
IO]
[“c-call”, “/c/temp/ruby/retry.rb”, 10, :write, #Binding:0x100f4c30,
IO]
[“c-return”, “/c/temp/ruby/retry.rb”, 10, :write, #Binding:0x100f4b10,
IO]
[“c-return”, “/c/temp/ruby/retry.rb”, 10, :puts, #Binding:0x100f49f0,
Kernel]
[“line”, “/c/temp/ruby/retry.rb”, 11, nil, #Binding:0x100f48d0, false]
[“c-call”, “/c/temp/ruby/retry.rb”, 11, :+, #Binding:0x100f47b0,
Fixnum]
[“c-return”, “/c/temp/ruby/retry.rb”, 11, :+, #Binding:0x100f4690,
Fixnum]
[“line”, “/c/temp/ruby/retry.rb”, 5, :repeat, #Binding:0x100f4570,
Object]
[“line”, “/c/temp/ruby/retry.rb”, 5, :repeat, #Binding:0x100f4450,
Object]
[“return”, “/c/temp/ruby/retry.rb”, 3, :repeat, #Binding:0x100f4330,
Object]
[“c-call”, “/c/temp/ruby/retry.rb”, 9, :>=, #Binding:0x100f4210,
Fixnum]
[“c-return”, “/c/temp/ruby/retry.rb”, 9, :>=, #Binding:0x100f40f0,
Fixnum]
[“call”, “/c/temp/ruby/retry.rb”, 2, :repeat, #Binding:0x100f3ee0,
Object]
[“line”, “/c/temp/ruby/retry.rb”, 3, :repeat, #Binding:0x100f3e98,
Object]
[“c-call”, “/c/temp/ruby/retry.rb”, 3, :to_s, nil, FalseClass]
[“c-return”, “/c/temp/ruby/retry.rb”, 3, :to_s, nil, FalseClass]
[“c-call”, “/c/temp/ruby/retry.rb”, 3, :puts, #Binding:0x100f3b38,
Kernel]
[“c-call”, “/c/temp/ruby/retry.rb”, 3, :write, #Binding:0x100f3a18,
IO]
condition: false[“c-return”, “/c/temp/ruby/retry.rb”, 3, :write,
#Binding:0x100f38f8, IO]
…
You see that it goes back to line 9 reevaluating the >=. If you ask why
this is (i.e. design rationale), you probably have to ask Matz. HTH
Kind regards
robert