ネストされたブロックからの脱出
catch,throwでネストされたブロックを一気に抜けます。throw で抜けた場合、catchの戻り値はthrowの第2引数です。
puts catch(:A) { 5.times {|i| puts "outer loop:" << i.to_s 5.times {|j| puts "inner loop:" << i.to_s << "-" << j.to_s throw :A, "cancel" } } "end" }
出力:
outer loop:0 inner loop:0-0 cancel
throw が実行されなければ、ブロックをただ実行するだけです。この場合、戻り値はブロックの値となります。
puts catch(:A) { 5.times {|i| puts "outer loop:" << i.to_s 5.times {|j| puts "inner loop:" << i.to_s << "-" << j.to_s } } "end" }
出力:
outer loop:0 inner loop:0-0 inner loop:0-1 inner loop:0-2 inner loop:0-3 inner loop:0-4 outer loop:1 inner loop:1-0 inner loop:1-1 inner loop:1-2 inner loop:1-3 inner loop:1-4 outer loop:2 inner loop:2-0 inner loop:2-1 inner loop:2-2 inner loop:2-3 inner loop:2-4 outer loop:3 inner loop:3-0 inner loop:3-1 inner loop:3-2 inner loop:3-3 inner loop:3-4 outer loop:4 inner loop:4-0 inner loop:4-1 inner loop:4-2 inner loop:4-3 inner loop:4-4 end
throw で指定したシンボルに対応するcatchがなければエラーとなります。
puts catch(:A) { 5.times {|i| puts "outer loop:" << i.to_s 5.times {|j| puts "inner loop:" << i.to_s << "-" << j.to_s throw :B, "cancel" } } "end" }
xxx/catch_throw.rb:50:in `throw': uncaught throw `B' (NameError)