jobs.each do |job|
msg job.name do
break if stop_all_jobs?
job.run!
end
end
def msg(msg, &block)
puts 'START ' + msg
yield
puts 'END ' + msg
end
上記の例では、break は期待どおりにループから抜け出しません。メッセージコードブロックからのみ抜け出すことができます。
これは少し奇妙に思えますが、コンテキストに基づいていると思います。つまり、生成されたコード ブロック内のコードからループを抜け出すにはどうすればよいでしょうか?
1 つの方法は、スロー/キャッチを使用することです。いいえ、例外ではありません。Ruby には、すべてのオーバーヘッドなしで、例外と同じように機能する別のフロー制御機能があります (ただし、それを使用する際にオーバーヘッドがないことは認められませんが)。
catch :stop_all_jobs do
msg job.name do
throw :stop_all_jobs if stop_all_jobs?
job.run!
end
end
catch ブロックの結果となる値を 2 番目の引数として渡してスローすることもできます。
もちろん、より読みやすい解決策となる可能性があるのは、コードをメソッドにまとめて、break の代わりに return を使用することです。しかし、それはそれほど面白くありません。