酒と泪とRubyとRailsと

Ruby on Rails と Objective-C は酒の肴です!

ネストの深い(多重)ループを抜け出す - Rubyのthrow/catch

Where?

Rubyの標準メソッドにthrow/catchはネストの深いループ(多重ループ)を一発で抜けだしたい場合などに使えそうなので、紹介します。


throw/catchの説明

次のサンプルソースを使って、throw/catchを説明します。

1
2
3
4
5
6
7
8
9
def ween
  puts 'ween'
  throw :symbol
end

catch(:symbol) do
  ween
  puts 'hoge'
end
コンソール
1
2
ruby throw.rb
> ween # hoge => 出力されず

つまり「throw/catch」は「raise/rescue」とほぼ同じ動きをします。

# 両者の違い
* throw/catch => symbol
* raise/rescue => Error(例外)

throw/catchを使ったネストの深いループからの脱出

throw/catchはsymbolのため、通常のネストの深いループから抜け出したい場合などにも使えます。

1
2
3
4
5
6
7
8
9
10
catch(:break_loop) do
  3.times do |i|
    3.times do |j|
      puts "i, j = #{i}, #{j}"
      throw :break_loop if i == 2 and j == 1
    end
  end
end

puts "loop out"
コンソール
1
2
3
4
5
6
7
8
9
10
ruby throw2.rb
>i, j = 0, 0
>i, j = 0, 1
>i, j = 0, 2
>i, j = 1, 0
>i, j = 1, 1
>i, j = 1, 2
>i, j = 2, 0
>i, j = 2, 1
>loop out

おすすめの書籍