※この記事は初学者が自分なりにまとめたものになります。
目次
はじめに
今日は、Rubyにおいて2重3重に重なったループを一撃で抜ける方法を調べてみました!
大域脱出とは
この何重にも重なったループを抜け出す処理を"大域脱出”と言います。
<代表的な大域脱出方法2選>
以下は、Rubyの大域脱出の方法で代表的なもの2つです。
1. return
メソッドやブロックの実行を終了し、呼び出し元に制御を戻します。メソッドの中で使われることが多いです。
2. throw catch
特定のスコープから大域脱出するための方法で、throwは指定されたシンボルを投げ、対応するcatchブロックに制御を戻します。複雑な制御フローが必要な場合に使われます。
どちらの方法でも多重ループから抜け出すことができるのですが、明確な違いがあります。
メソッド内で多重ループの処理があって、そこから大域脱出した時に同メソッド内の後の処理を実行するのかどうかという点です。
実際のコードで見てもらった方が早いと思います。
return
このコードでは、2つの範囲オブジェクト (1..3) を使って各ループが1から3までの値を順に取り、全ての組み合わせを総当たりで処理します。
特定の条件が満たされた場合に、returnを使ってメソッド全体から抜け出します。
returnに行く条件は、if文で2.2の組み合わせの時としています。
そのため、returnされる2.2以降の2.3, 3.1, …といった組み合わせは出力されません。
def nested_loops_with_return
(1..3).each do |i|
(1..3).each do |j|
if i == 2 && j == 2
# 内側のループからメソッド全体を抜け出す
return "Exited with return"
end
puts "i: #{i}, j: #{j}"
end
end
"This line will not be executed"
end
puts nested_loops_with_return
# Output:
# i: 1, j: 1
# i: 1, j: 2
# i: 1, j: 3
# i: 2, j: 1
# Exited with return
throw catch
このコードも、2つの範囲オブジェクト (1..3) を使って各ループは1から3までの値を順に取り、全ての組み合わせを総当たりで処理します。
特定の条件が満たされた場合に、throwを使ってcatchブロックから抜け出します。
catchブロックから抜け出すのみなので、メソッド内のその後の処理を実行することができます。
throwは名前のとおり、指定のシンボルを投げます。
そして、対応するcatchブロックに制御を戻します。
今回、指定のシンボルは:exit_pointとしました。
def nested_loops_with_throw_catch
result = catch(:exit_point) do
(1..3).each do |i|
(1..3).each do |j|
if i == 2 && j == 2
# 内側のループから外側のループ全体を抜け出す
throw :exit_point, "Exited with throw and catch"
end
puts "i: #{i}, j: #{j}"
end
end
end
# 外側のループ全体を抜け出した後の処理
puts "This line is inside the method after throw"
puts result
end
nested_loops_with_throw_catch
# Output:
# i: 1, j: 1
# i: 1, j: 2
# i: 1, j: 3
# i: 2, j: 1
# This line is inside the method after throw
# Exited with throw and catch
まとめ
メソッドから抜け出すのがreturn、
ブロックから抜け出すのがthrow catchです。
使い分けのポイント
- メソッド全体を終了させたい場合:
- returnを使用します。メソッドの途中で処理を終了し、呼び出し元に制御を戻したい場合に適しています。
- ネストされたループや特定のスコープから抜け出したい場合:
- throw catchを使用します。特定の条件が満たされた場合に、ネストされたループや複雑な制御フローから抜け出し、その後の処理を続けたい場合に適しています。
3.後続の処理が必要かどうか:
- returnはメソッド全体を終了させるため、後続の処理は実行されません。
- throw catchは特定のスコープから抜け出すため、後続の処理を実行することができます。
状況に応じて使い分けましょう!