システム開発において、繰り返し処理はどのプログラミング言語を利用する場合でも必須となる知識です。
本記事では、Rubyでのloopメソッドを利用した繰り返し処理の使い方を解説しながら、類似メソッドとの違いについてご紹介していきます。
loopメソッドとは
loopメソッドは、Kernelクラスより提供されているメソッドで、終了条件のない繰り返し処理(無限ループ)が実行されます。
loopメソッドの基本構文
loopメソッドの記述方法について、まずは確認していきます。
loop { 処理 }
「処理」部分に記述した内容が繰り返し実行されることになります。
動作は同じですが、下記のように記述することも可能です。
loop do 処理 end
同じく「loop do」と「end」の間に記述された「処理」部分が繰り返し実行されます。
loopメソッドの制御方法
loopメソッドは終了条件のない繰り返し処理を実現しますが、処理を制御するための方法がいくつか提供されています。
- break: 繰り返し処理の中断
- next: 次の繰り返し処理へ移動
- redo: 同じ繰り返し処理の実行
loopメソッドを使ったサンプル
loopメソッドを使ったサンプルコードで具体的な使い方を確認してみましょう。
breakで処理を抜けるサンプル
loopメソッドを利用する際、無限ループのまま放置することはなく、基本的にbreakを指定して条件により繰り返し処理を中断します。
下記のサンプルではnumの数値を繰り返し処理で1つずつ加算し、numの値が3になった時点で繰り返し処理を中断するコードです。
num = 0 loop { p num num += 1 if num > 2 break end }
実行結果が下記です。
0 1 2
ループがネストしている場合
ループがネストしている場合、breakで繰り返し処理を抜けるのはbreakを記述した場所から最も内側の繰り返し処理のみとなります。
num1 = 0 loop { num1 += 1 p "外側ループ: " + num1.to_s num2 = 1 loop { p "内側ループ: " + num2.to_s num2 += 1 if num2 > 3 break end } if num1 > 1 break end }
実行結果が下記です。
"外側ループ: 1" "内側ループ: 1" "内側ループ: 2" "内側ループ: 3" "外側ループ: 2" "内側ループ: 1" "内側ループ: 2" "内側ループ: 3"
内側のループでbreakが実行された場合でも、外側ループの処理は引き続き実行されていることをご確認頂けます。
nextを使ったサンプル
nextを利用するとnext以降の処理をスキップした上で、引き続き繰り返し処理が実行されます。
num = 0 loop { num += 1 if num == 2 next elsif num > 4 break end p num }
実行結果が下記です。
1 3 4
「num」が「2」の場合、コンソール出力の処理が実行されないためサンプルのような結果となります。
redoを使ったサンプル
redoを利用する場合、同じ条件で繰り返し処理を再実行することが可能です。
ただしloopメソッドを利用している場合、繰り返し処理自体に終了条件や範囲が設定されているわけではないため、「next」を利用する場合と処理内容は変わりません。
num = 0 loop { num += 1 if num == 2 redo elsif num > 4 break end p num }
実行結果が下記です。
1 3 4
「redo」が実行された際、コンソール出力処理が実行されず次の繰り返し処理に移ります。
loopメソッド以外の繰り返し処理
繰り返し処理を実現するためには、loopメソッド以外にもいくつかの記述方法が存在します。
中でも頻繁に利用される記述方法を紹介しますので、それぞれの処理の違いを確認しておきましょう。
for文
繰り返し処理といえばfor文が最も馴染みがある方も多いでしょう。
Rubyでも利用することが可能で下記のように記述します。
for num in 1..10 do p num end
実行結果が下記です。
1 2 3 4 5 6 7 8 9 10
サンプルの場合1から10までの範囲を指定して、各値を変数numに格納しコンソール出力するサンプルです。
loopメソッドと異なり、breakを記述しなくても指定した範囲の処理が終了すれば繰り返し処理は終了となります。
eachメソッド
配列やハッシュに対して繰り返し処理を行う場合、よく利用されるのが「each」メソッドです。
配列の場合
animals = ["さる", "とり", "いぬ"] animals.each do |animal| p animal end
実行結果が下記です。
"さる" "とり" "いぬ"
配列に格納された値が順番に変数「animal」に設定され、コンソールに出力されるサンプルです。
ハッシュの場合
animals = {"さる": 5, "とり": 3, "いぬ": 7} animals.each do |name, age| p "名称: #{name} 年齢: #{age}" end
実行結果が下記です。
"名称: さる 年齢: 5" "名称: とり 年齢: 3" "名称: いぬ 年齢: 7"
「name」と「age」にそれぞれハッシュの「key」と「value」が順番に設定され、コンソール出力されるサンプルです。
「each」メソッドの場合も「loop」メソッドと異なり、指定したオブジェクトの範囲内でのみ繰り返し処理が実行されます。
while文
while文では指定した条件が「true」の間、繰り返し処理を実行します。
num = 0 while num < 10 p num num += 1 end
実行結果が下記です。
0 1 2 3 4 5 6 7 8 9
サンプルの場合、指定した条件「numの値が10未満」が成立している間繰り返し処理が実行されています。
「while」文も終了条件を明示する必要があるため、無限ループを実現する「loop」メソッドとは処理内容が異なります
timesメソッド
timesメソッドを利用すると、繰り返し処理を実行したい回数を明示することが可能です。
5.times do p "指定した回数繰り返します。" end
実行結果が下記です。
"指定した回数繰り返します。" "指定した回数繰り返します。" "指定した回数繰り返します。" "指定した回数繰り返します。" "指定した回数繰り返します。"
サンプルの場合、「5」を指定しているため、繰り返し処理が5回実行されていることをご確認頂けます。
さいごに: Rubyのloopメソッドで意図しない無限ループを起こさないよう注意
本記事では、loopメソッドの使い方を中心に、Rubyでの繰り返し処理の記述法による違いをご紹介してきました。
loopメソッドは無限ループを実現するためのメソッドではありますが、実際のシステム開発で無限ループを起こしたいケースというのはほとんどありません。
あらかじめ条件や回数を指定する必要がなく繰り返し処理を実現出来るため便利なメソッドではありますが、意図しない無限ループを引き起こしてプログラムを停止させてしまわないよう十分に注意した上で利用するようにしましょう。
基本的に無限ループを意図的に起こすことはないため、loopメソッドは「break」とセットで利用されます。