Rubyでプログラムを記述する際、特定の条件を満たすまで処理を繰り返したい場面が頻繁に登場します。
繰り返し処理を実現する制御構造の一つに、until文があります。
until文は「条件が真 (true) になるまで処理を繰り返す」という性質を持っており、while文とは対照的な動きをします。
条件が偽 (false) である間だけループを継続したい場合に、コードの可読性を高める強力なツールとなります。
この記事では、until文の基本的な書き方から実用的な使い方、while文との使い分けについて詳しく解説します。
Rubyのuntil文とは
until文は、指定した条件式が 真 (true) になるまで 繰り返し処理を実行する制御構造です。
言い換えると、条件式が偽 (false) である限り、ブロック内の処理が実行され続けます。
他のプログラミング言語ではあまり見かけない構文ですが、Rubyらしい「直感的なコード」を書くために非常に役立ちます。
until文の基本的な構文
until文の最も標準的な書き方は、以下の通りです。
# 基本的な構文
until 条件式 do
# 条件が偽の間、繰り返し実行したい処理
end
なお、do は省略して記述することが一般的です。
具体的な使用例
実際に変数を使用して、カウントアップを行う簡単な例を見てみましょう。
i = 0
# iが5になるまで(i < 5 の間)繰り返す
until i == 5
puts "現在の値は #{i} です"
i += 1 # 変数を更新して終了条件に近づける
end
このプログラムを実行すると、以下の結果が得られます。
現在の値は 0 です
現在の値は 1 です
現在の値は 2 です
現在の値 is 3 です
現在の値は 4 です
i の値が5になった瞬間に条件式が真となり、繰り返し処理が終了します。
until文とwhile文の違い
until文と非常によく似た制御構造に while 文があります。
これら二つの違いを一言で言えば、「繰り返しを継続する条件の判定が逆」である点です。
論理的な比較
while文は「条件が真である間」繰り返しますが、until文は「条件が真になるまで (偽である間) 」繰り返します。
以下の表で、その違いを整理してみましょう。
| 構文 | ループが継続される条件 | ループが終了するタイミング |
|---|---|---|
| while文 | 条件式が 真 (true) のとき | 条件式が 偽 (false) になったとき |
| until文 | 条件式が 偽 (false) のとき | 条件式が 真 (true) になったとき |
どちらを使うべきか
論理的には while !(条件) と until 条件 は同じ動作をします。
しかし、Rubyでは「否定的な条件を避けて、より自然言語に近い形で記述する」ことが推奨されます。
例えば、「エラーが発生していない間繰り返す」よりも「エラーが発生するまで繰り返す」と書くほうが直感的な場合があります。
条件が肯定的に表現できる方を選択することで、コードの読みやすさが大幅に向上します。
until文の便利な書き方
Rubyでは、プログラムをより簡潔に記述するためのテクニックが用意されています。
until修飾子 (後置until)
処理が1行だけの場合は、処理の後に until を記述する until修飾子 が利用可能です。
price = 100
price += 10 until price >= 150
puts price
このコードは、price が150以上になるまで、10を加算し続けます。
150
非常にコンパクトに書けるため、ガード節や簡単な初期化処理などで重宝されます。
begin…endを使用した後置判定
通常のuntil文は、処理を実行する前に条件判定を行いますが、最低でも1回は処理を実行したい場合があります。
その場合は begin...end ブロックと組み合わせます。
n = 10
begin
puts "実行されました"
n += 1
end until n > 5
この場合、最初に条件 n > 5 を評価するのではなく、一度 puts を実行してから判定が行われます。
until文でのループ制御 (breakとnext)
繰り返し処理の中で、特定の条件下でループを抜けたり、次の回へスキップしたりすることが可能です。
breakによる強制終了
break を使用すると、until文の条件が真になる前であっても、ループを完全に終了させることができます。
count = 0
until count == 10
if count == 3
puts "3に到達したので終了します"
break
end
count += 1
end
3に到達したので終了します
nextによる処理のスキップ
next を使用すると、それ以降の処理を飛ばして、次のループ判定(条件評価)に移動します。
count = 0
until count == 5
count += 1
if count == 3
next # 3のときは出力をスキップ
end
puts "#{count}回目のループです"
end
1回目のループです
2回目のループです
4回目のループです
5回目のループです
実戦的なuntil文の活用シーン
実際の開発でuntil文がどのような場面で使われるか、具体的なイメージを掴んでおきましょう。
ユーザー入力のバリデーション
「正しい値が入力されるまで、入力を求め続ける」という処理は、until文の得意分野です。
input = ""
# 入力が "yes" になるまで繰り返す
until input == "yes"
print "続行するには 'yes' と入力してください: "
input = gets.chomp
end
puts "手続きを開始します。"
このように、「期待する状態(この場合はyes)」を終了条件に置くことで、ロジックが分かりやすくなります。
キューの処理
配列などのデータ構造が空になるまで処理を継続する場合にも利用されます。
tasks = ["メール送信", "データ集計", "レポート作成"]
until tasks.empty?
current_task = tasks.shift
puts "#{current_task} を実行中..."
end
「タスクリストが空である」という完了状態を until に渡すことで、自然な日本語のようなコードになります。
until文を使用する際の注意点
until文を使う上で、いくつか注意すべきポイントがあります。
無限ループの回避
繰り返し処理全般に言えることですが、「条件がいつか必ず真になること」を保証しなければなりません。
ループ内で条件に関わる変数が更新されない場合、プログラムは永久に終了しなくなります。
もし意図せず無限ループに陥った場合は、ターミナルで Ctrl + C を押して強制終了してください。
可読性の優先
「もし条件が複雑になりすぎるなら、until文ではなくwhile文やeachメソッドを検討する」ことも大切です。
Rubyには each や map などの強力なイテレータが備わっているため、単純な配列操作であればuntil文を使わない方が簡潔になる場合が多いです。
文脈に合わせて、「読んだ瞬間に何をしているか理解できるか」を基準に選択しましょう。
まとめ
Rubyの until 文は、条件が真になるまで処理を繰り返すための便利な構文です。
while文の逆の論理を持つため、否定 (not) を使わずに「〜になるまで」という意図を直接表現できるのが最大のメリットです。
基本的な使い方のポイントをまとめると以下の通りです。
- until 条件式:条件が偽の間繰り返し、真になると終了する。
- 後置until:1行で簡潔に記述したい場合に有効。
- whileとの使い分け:条件を肯定的に書ける方を選択して可読性を高める。
- break/next:ループの途中で動作を制御するために使用する。
これらの特性を理解して、より読みやすく美しいRubyコードの記述に役立ててください。
