多重ループからの脱出
単純なループやイテレータは、breakで脱出できる。
num = [1,2,3,4,5,6,7,8,9,10] num.each do |i| break if i > 5 puts i end puts "----------------------" for i in num break if i > 5 puts i end
1 2 3 4 5 ---------------------- 1 2 3 4 5
ただしこれは最も内側のループに限る。
num = [1,2,3,4,5] num.each do |i| num.each do |j| break if j > 1 puts j end end
1 # 5回外側のループが実行される 1 1 1 1
Perlだとループにラベル貼って、そこに飛ぶ!という感じ。
my @num = 1 .. 5; OUT: for my $i (@num) { IN: for my $j (@num) { last OUT if $i > 1; say $i; } }
Rubyだと少し工夫が必要で、外側をcatchで囲ってシンボルを指定して、throwでそのシンボルが投げられたらcatchがキャッチ!となるみたい。
num = [1,2,3,4,5] catch(:out) do num.each do |i| num.each do |j| throw :out if j > 1 puts j end end end
1 # throw で catch の範囲を抜けた
この辺の制御がオブジェクト指向で煩雑になるってことなのかな。
その分、逆に必要性は薄れてるともいえるか。