Rubyでもループ処理はプログミングの基本です。他のプログラミング言語でも使えるforやwhileを使った構文が使えます。しかしRubyはオブジェクト指向なスクリプト言語です。他のプログラミング言語とは違ったループ処理を使ったプログラムも作れます。
今回はRubyで使えるループ処理の書き方について詳しく解説します。
ループ処理の基本
プログラミングを習ったことがある方なら、ループ処理とはどのようなものかを知っているでしょう。簡単に解説すると、ループとは特定の条件下において同じ処理を繰り返すことです。そのため繰り返し処理とも呼ばれています。
Rubyに限らずループ処理は全てのプログラミング言語で利用でき、1つのプログラムで何度も使われる処理です。次からこのループ処理がよく使わえるケースについて紹介します。
配列に対して使う
ループ処理がよく使われるケースとして真っ先に挙げられるのが配列に対する処理です。配列の先頭から順に同じ処理を適用するケースで、配列の添え字が配列の最後の添え字になるまでの間、その要素に対してループの中で同じ処理を適用します。
なお配列も多くのプログラミング言語で扱える機能で、複数のデータをあたかも1つの変数で扱える便利な変数です。そのためいろいろな場面で使われますが、配列の全ての要素に対して処理するのにループ処理が使われます。
ただしRubyには配列を処理する便利なメソッドが幾つもあるので、処理によってはループ処理ではなくメソッドを指定するだけで十分なケースもあります。
終わるまで処理する
先ほど紹介した配列は末尾が幾つか調べればループを回す回数を調べることが可能ですが、データによっては終わりが解らないケースもあります。そのような場合、データが終わるまで同じ処理を繰り返すためにループ処理を作成します。
例えばファイルからデータを読み込む場合、そのファイルの最後のデータを読み込んだら繰り返しを終了するループを用います。なおRubyでもそのようなループでファイルを読み込めますが、ファイルの全ての内容を配列に読み込み処理することも可能です。
またRubyでも、条件が一致するまで同じ処理を繰り返すプログラムを組めますが、メソッドの組み合わせで別の方法を使えるケースもあります。なぜループ処理を使うかをよく考えてプログラムに利用してください。
他の処理を待つ
組み込み用のプログラムでよく使われるループ処理に、他の時間がかかる処理が終わるまで、何もしないで待つ処理があります。
例えば、2つのプログラムが同時に実行している場合、一方の処理が終わったら、もう一方がその結果を使って処理するケースがよくあります。そのような場合、一方の処理が終わるまで、もう一方は何もしないで待つ処理を作りますが、この処理にループが使われます。そして処理が終わった合図を受け取り、ループを終了して次の処理を実行するのが一般的です。
Rubyでは並列処理のプログラムを作ることが可能なため、こういった何もしないで待つ際にループ処理を利用できます。
Rubyで使えるループ
Rubyはオープンソースのオブジェクト指向なスクリプト言語で、必ずしもループを使わなくても繰り返し処理と同じことが可能です。とはいえループを作るための制御構造やメソッドも用意されているので、それをうまく活用してください。
Rubyで使えるループを作るための制御構造やメソッドとは、次のとおりです。
while : 繰り返しの制御構文
until : 繰り返しの制御構文
for : 繰り返しの制御構文
each : 配列とハッシュで使えるメソッド
loop : 繰り返し処理を作るためのメソッド
times : 数字オブジェクトで使えるメソッド
downto : 数字オブジェクトで使えるメソッド
次からRubyで使えるループのためのメソッドを簡単に紹介します。
while構文とuntil構文
Rubyの文法はC言語の影響を受けているので、C言語と同じ制御構文が採用されています。そしてwhileとuntilは、C言語でも使える機能が同じ制御構文です。なお、whileは続く式が真の間、本体を繰り返し、untilは続く式が偽の間、本体を繰り返します。
whileの文法
while 式 [do]
本体
end
untilの文法
until 式 [do]
本体
end
for構文
forは、続くの変数を同じく指定された範囲の間で変化させて、その範囲の中で処理をループするための制御構文です。なお同じような処理を配列の後で説明するeachメソッドなどでも作れますが、for文はブロックではないため、ローカル変数のスコープに影響を与えません。
forの文法
for 変数 in 範囲 [do]
本体
end
for文では複数の変数を指定することが可能です。ただし、その場合はinに続く範囲で複数の範囲を指定します。
eachメソッド
eachメソッドは配列またはハッシュのオブジェクトで利用できるメソッドで、指定したブロックの中にループ処理を記述します。そして、配列オブジェクトでは||に囲まれた1つの変数に配列の値を、またハッシュオブジェクトでは||に囲まれた2つの変数にキーと値を格納し、ブロックの中で使用します。
配列オブジェクトのeachメソッドの文法
配列オブジェクト.each do |変数|
ブロック
end
ハッシュオブジェクトのeachメソッドの文法
ハッシュオブジェクト.each do |キー, 変数|
ブロック
end
loopメソッド
loopメソッドは最も上位のクラスに属しており、オブジェクトに接続せずに使える、ループを作るためのメソッドです。そしてeachメソッドと同じようにブロックの中に処理を記述します。
そしてブロックに記述した処理を永遠にループするため、ブロック内に中断するための処理が必要です。ブロック内にループを中断するbreak文を利用した処理を記述してください。
loopメソッドの文法
loop do
ブロック
end
timesメソッド
timesメソッドは整数のオブジェクトで利用できるメソッドで、その数だけブロックをループします。また単純に繰り返すだけでなく、今の数字を||で囲んだ変数に代入して、ブロックの中で利用することも可能です。
timesメソッドの文法
整数のオブジェクト.times do |n|
ブロック
end
なおtimesメソッドは0からオブジェクトの数字までループしますが、Rubyには1からオブジェクトの数字までループするuptoメソッドもあるので、目的に応じて使い分けてください。
downtoメソッド
先ほど紹介したtimesメソッドとuptoメソッドは指定した数まで数字を増やすループ処理でしたが、downtoメソッドは同じく数字オブジェクトを対象に、その数字から1までの間ループするメソッドです。
downtoメソッドの文法
整数のオブジェクト.downto do |n|
ブロック
end
ループを使わずに済むケース
もし配列を対象にした処理でループを使おうとしているのなら、ぜひ、配列オブジェクトで使えるメソッドを調べてみてください。配列オブジェクトならfor文の代わりにeachメソッドを使うことで、より簡潔にループ処理を記述できます。さらに他の配列オブジェクトのメソッドを使うことで、よりシンプルで読み易いなプログラムが書けるかもしれません。
例えば配列の要素に同じ処理を適用するだけなら、配列オブジェクトのmapメソッドが使えます。さらに配列が数字ならその合計を計算するメソッドや、条件に一致する要素のみを抽出するメソッドなどもあるので、ぜひそのようなメソッドをうまく利用してください。
まとめ
Rubyではwhile文やfor文といった制御構文が使えるので、他のプログラミング言語と同じようなループ処理のプログラムを作れます。ただし、オブジェクト指向のRubyなら、対象となるオブジェクトで使えるメソッドをうまく活用したループ処理を作ることも可能です。
このようにRubyには範囲を指定したループ処理を作る方法がいろいろあるので、ケースに応じて見やすいプログラムを書けるようになりましょう。