Ruby while と until ループ
ループはプログラミングにおける基礎的なコンセプトであり、特定のコードブロックを繰り返しエグゼキュート(実行)することを可能にします。
本章では、Ruby における while および until ループについて探求し、特定のコンディションに基づいてプログラムのフローをコントロールするためのパワフルなアプローチを提供します。
1. while ループ
Ruby における while ループは、指定されたコンディションが true である間、コードブロックを継続的にエグゼキュートします。そのベーシックなシンタックスは以下の通りです:
while condition do
# エグゼキュートするコード
endまたは、より一般的な do を省略した記述法です:
while condition
# エグゼキュートするコード
end各イテレーションの前に、プログラムは condition(コンディション)をエバリュエート(評価)します。コンディションが true の場合、ループ内部のコードがエグゼキュートされます。ループ内のコードのエグゼキュートが完了すると、再びコンディションがチェックされます。このプロセスは、コンディションが false になるまでリピートされます。
1.1 ベーシックな while ループのサンプル
1から5までのナンバーをプリントする、while ループを使用したシンプルなサンプルを見てみましょう:
counter = 1 # カウンターのバリアブルをイニシャライズ(初期化)する
while counter <= 5 # コンディション:counter が 5 以下である限り、ループは継続する
puts counter # counter の現在の値をプリントする
counter += 1 # counter を 1 インクリメントする (counter = counter + 1 と等価)
end
puts "ループが終了しました!" # これはループがコンプリートした後にプリントされるこのサンプルにおいて:
- バリアブル
counterを1にイニシャライズします。 whileループはcounter <= 5が成立するかどうかをチェックします。- コンディションが true の場合、
counterの値をプリントし、その後counterを1インクリメントします。 - ループは
counterが6になるまで継続し、その時点でcounter <= 5というコンディションが false になり、ループがターミネート(終了)します。 - ループ終了後、
puts "ループが終了しました!"のコードがエグゼキュートされます。
1.2 無限ループ
非常に重要なポイントとして、while ループのコンディションが最終的に false になることを必ず保証する必要があります。そうでない場合、永遠にランし続ける無限ループをクリエイトしてしまいます。例:
# このサンプルには注意してください - 無期限にランし続けます!
# x = 1
# while x == 1
# puts "これは永遠にプリントされ続けます!"
# endこのサンプルでは、x は常に 1 と等しいため、x == 1 のコンディションは永遠に true となり、ループは絶対に終了しません。無限ループをストップさせるには、通常マニュアルでプログラムをターミネートする必要があります(例:ターミナルで Ctrl+C を押下する)。
1.3 ユーザーインプットと while ループのコンバイン
while ループは、特定のコンディションが満たされるまで、ユーザーにインプットを継続的にプロンプトするために頻繁にユースされます。例:
input = ""
while input != "quit"
print "コマンドをインプットしてください ('quit' でターミネート): "
input = gets.chomp # ユーザーのインプットを取得し、末尾のニューライン(改行)をリムーブする
puts "あなたのインプット: #{input}" unless input == "quit" # インプットが "quit" でない限り、そのインプットをプリントする
end
puts "プログラムをエグジットしています。"このサンプルにおいて:
inputバリアブルを空のストリングにイニシャライズします。inputが"quit"と等しくない限り、whileループは継続します。- ループ内部で、プログラムはユーザーにインプットのコンテンツをプロンプトします。
gets.chompメソッドはユーザーから1行のインプットをリードし、末尾のニューラインキャラクターをリムーブします。- その後、インプットされたコンテンツが
"quit"でない限り、プログラムはインプットされたコンテンツをユーザーにプリントして返します。 - ユーザーが
"quit"をインプットした時点で、コンディションinput != "quit"が false となり、それに伴いループがターミネートします。
1.4 マルチプルなコンディションを持つ while ループ
ロジカルオペレーターである && (AND) や || (OR) を使用して、while ループ内で複数のコンディションをコンバインすることができます。
counter = 1
limit = 10
flag = true
while counter <= limit && flag
puts "カウンター: #{counter}"
counter += 1
flag = false if counter > 5 # counter が 5 を超えた場合、flag を false にセットする
end
puts "ループが終了しました。カウンター: #{counter}, フラグ: #{flag}"このサンプルでは、counter が limit 以下であり、かつ flag が true である限り、ループは継続します。これらのコンディションのうちいずれかが false になった瞬間に、ループはターミネートします。
2. until ループ
until ループは while ループの真逆のアプローチを取ります。これは指定されたコンディションが false である間、コードブロックを継続的にエグゼキュートします。そのベーシックなシンタックスは以下の通りです:
until condition do
# エグゼキュートするコード
endまたは、より一般的な記述法:
until condition
# エグゼキュートするコード
end同様に、各イテレーションの前に condition がエバリュエートされます。コンディションが false の場合、ループ内部のコードがエグゼキュートされます。コードのエグゼキュートが完了すると、再びコンディションがチェックされます。このプロセスは、コンディションが true になるまでリピートされます。
2.1 ベーシックな until ループのサンプル
以前の1から5までのナンバーをプリントするサンプルをリライトしますが、今回は until ループを使用します:
counter = 1
until counter > 5 # コンディション:counter が 5 より大きくない限り、ループは継続する
puts counter
counter += 1
end
puts "ループが終了しました!"このコードがジェネレートするアウトプットは while ループのサンプルと完全に同一ですが、ロジックはリバース(反転)されています。ループは、counter が 5 より大きくなるまで継続します。
2.2 ユーザーインプットと until ループのコンバイン
while ループと同様に、until ループもユーザーにインプットを継続的にプロンプトするためにユースできます。以前のユーザーインプットのサンプルをモディファイしてみましょう:
input = ""
until input == "quit"
print "コマンドをインプットしてください ('quit' でターミネート): "
input = gets.chomp
puts "あなたのインプット: #{input}" unless input == "quit"
end
puts "プログラムをエグジットしています。"このコードのビヘイビア(振る舞い)は while ループのバージョンと完全に一致しますが、ここでのロジックは「ユーザーが "quit" をインプットするまでループが継続する」というものになります。
3. while と until の使い分け
while と until ループはどちらも類似のタスクをコンプリートできます。どちらを選択するかは、通常、コードのリーダビリティおよびプログラムの特定のロジックに依存します。
whileを使用するケース: コンディションが true である時にコードブロックをエグゼキュートしたい場合。untilを使用するケース: コンディションが true になるまでコードブロックをエグゼキュートしたい場合。
総じて、コードの意図をより容易に理解でき、推論しやすいループのストラクチャーを選択することがベストプラクティスです。
4. ループコントロール・ステートメント:break と next
break と next については後続の章で詳細に解説しますが、これらは while や until ループとコンバインして頻繁に使用されるため、ここで簡潔にイントロダクションしておく必要があります。
break: ループのコンディションに関わらず、即座にループをエグジット(脱出)します。next: 現在のイテレーションの残りの部分をスキップし、直接ループの次のイテレーションへと進みます。
以下は、while ループ内で break を使用するクイックなサンプルです:
counter = 1
while true # これは通常、無限ループになります
puts counter
counter += 1
break if counter > 5 # counter が 5 を超えた場合、ループをエグジットする
end
puts "ループが終了しました!"このサンプルにおいて、while ループは無期限にランするようにセットアップされています(while true)。しかし、break ステートメントにより、counter が 5 を超えた時点でループがセキュアにエグジットされることが保証されています。