プログラミングを学ぶと、if文による条件分岐の他に、Rubyのcaseのような複数の条件を分岐する書き方も習います。しかし、Rubyのcaseは、数字や文字を比較して分岐させる機能との他に、配列が使えたり、範囲が使えたりと、他のプログラム言語よりも多機能です。こういった機能を知らずに使っている方が多いのではないでしょうか。そこで今回は、case文の基本とRubyらしい応用的な書き方について解説します。
Rubyのcase文は他とは違う
Rubyのcaseを、他のプログラム言語、例えばC言語のswitchと同じものと考えているのであれば、考えを改めてください。確かに同じような書き方もできますが、オブジェクト指向のプログラム言語のRubyでは、caseが扱う対象もオブジェクトです。そのため、他のプログラム言語にはできない処理も書けます。
なお、そういった応用的な書き方の解説の前に、まずは、Rubyにおけるcase文の基本について解説します。
複数の候補から処理を分岐させる書き方
そもそもRubyではcase文、C言語などの他のプログラム言語ならswitch文は、複数の候補から処理を分岐させる処理を記述する構文です。同じ処理をif文でも書けますが、より見やすく簡潔に書くために、case文やswitch文が使われます。
例えば、下の2つの例を比べてみてください。上は複数のifで書いた例、その下は同じ処理をcase文で書いています。この両者を比較すると、下の方が簡潔で見やすいと感じることでしょう。
複数の条件をif文で分岐する例 if( sw === 1 ) then /* sw=1の場合の処理 */ elsif( sw === 2 ) then /* sw=2の場合の処理 */ elsif( sw === 3 ) then /* sw=3の場合の処理 */ else /* どの条件にも一致しない場合の処理 */ end
上の例をcase文で置き換えた例 case sw when 1 /* sw=1の場合の処理 */ when 2 /* sw=2の場合の処理 */ when 3 /* sw=3の場合の処理 */ else /* どの条件にも一致しない場合の処理 */ end
case文の基本
Rubyのおけるcaseの基本的な書き方は次のとおりです。
case 式
when 式 [then]
処理
…
end
まず、「case 式」から「end」までが、case文の範囲であり、その中に「when 式」やその条件に一致した場合の処理を記述します。「when 式」の後に、「then」を書いている例もありますが、省略しても構いません。また、どのwhenにも一致しない場合の処理を、「else」の次に書いてもいいし、省略しても構いません。
また、caseの次に記述する式と、whenの次に記述する式との一致判定は、演算子===を用いて行います。なお、Rubyにおける===は、数値の一致判定の他に、範囲内にあるかの判定や、正規表現にマッチするかを判定する演算子です。そのため、単純な一致の他に、範囲を使って判定や、正規表現を使った判定による条件分岐にも使えます。
さらに、サブクラスのインスタンス判定も行えるので、モジュールの所属関係をチェックする、といった処理も書けます。Rubyに詳しい方の中には、この機能を利用してRubyらしい書き方をされている方もいます。
1つのwhenに複数条件を指定する
先ほど紹介したように、Rubyのcase文における一致判定には===演算子が使われるので、数字や文字列の他にもいろいろなオブジェクトを使用できます。そのため、whenで配列を指定すれば、複数の数字や文字列との一致判定ができます。
次から、配列を使ったcase文の使い方について解説します。
whenに複数の条件を記述する方法
C言語などでは、条件に一致した際に実行する処理の最後にbreak文を入れることで、そこで処理を終了できます。そして、これをうまく使うと、複数の条件に一致するケースを書くことが可能です。しかし、Rubyにはbreak文がありません。その代わり、whenに「式,式」といったように、「,」で区切って指定することで、複数の条件を記述できます。
whenに複数の条件を記述する書き方
case 式
when 式1,式2
処理
…
end
この書き方を使えば、例えば次のように、変数swの値が1と2だったら処理するcase文が書けます。
1つのwhenで複数の数値と一致判定を行う例 case sw when 1,2 print("swが1または2に一致しました。\n") when 3 print("swが3に一致しました。\n") else print("一致しませんでした。") end
配列を用いたwhenに複数の条件を記述する方法
一つ前で説明した「式1,式2」の書き方は、whenに配列を指定したのと同じです。このようにwhenに配列の変数を指定しても構いません。ただし、配列変数を使用する場合は、変数名に「*」を付けます。
1つのwhenで配列を使う例 arr = [1,2] case sw when *arr print("swが1または2に一致しました。\n") when 3 print("swが3に一致しました。\n") else print("一致しませんでした。") end
whenの式で正規表現を使う
先ほど解説したように、Rubyのcase文における一致判定には===演算子が使われており、whenの式に正規表現を指定することが可能です。次から、正規表現を使ったcase文の書き方と例について、ご紹介します。
正規表現の指定方法
Rubyのcaseで指定した変数のチェックに、続くwhenで正規表現を使って一致確認する場合、正規表現を「/」で囲って指定します。なお、Rubyにおける正規表現では、メタ文字と呼ばれる特別な働きをする文字を使い、一致する条件を記述します。
例えば、半角数字の郵便番号をチェックする処理を組む際、数字7桁の場合と、数字3桁と数字4桁の間に「-」を入れた場合に、処理を切り替える場合、次のように記述します。
whenで正規表現を使った例 case postno when /\d{7}/ 数字7桁の場合の処理 when /\d{3}-\d{4}/ 数字3桁と数字4桁の間に「-」を入れた場合 else 間違った入力の場合 end
なお、Rubyでは、whenの他にも正規表現を使うケースがたくさんあります。Webプログラマーを目指すならRubyのマニュアルなどで正規表現を学び、使いこなせるようになりましょう。
whenの式で範囲を使う
先ほど、Rubyのcase文で配列を指定できると解説しましたが、同じように範囲を指定することも可能です。次から、whenの式に範囲を使ったcase文の使い方をご紹介します。
whenの式に範囲を使う基本
範囲を使ったcaseの書き方の基本は、whenで指定する式に「数字..数字」というrubyの範囲の書き方を使います。例えば、caseの式に数字を指定し、whenで指定した範囲に入っているかをチェックする場合の書き方は次のとおりです。
範囲を使ったcase文の例 case checkno when 1..5 print("1から5までの数字\n") when 6..9 print("6から9までの数字\n") else print("それ以外の数字\n") end
case文で範囲を使う応用例
先ほど、数字を使った範囲の書き方をご紹介しましたが、この機能は日付のチェックに応用できます。具体的には、caseの式に日付を指定し、whenで指定する式に「日付..日付」といった書き方で範囲を指定します。
case文で日付をチェックする例 require 'date' case today when Date.parse("2019/7/21")..Date.parse("2019/8/20") print("夏休み期間\n") when Date.parse("2019/12/25")..Date.parse("2020/1/7") print("冬休み期間\n") else print("それ以外の期間\n") end
上記の例では、「require ‘date’」でdateクラスを使い、日付の文字列「”2019/7/21″」を、Date.parseでDateクラスに変換し、それを「..」で繋いで期間を指定しています。そのため、caseの式にDateクラスの変数を指定すれば、whenで範囲に入っているかのチェックができます。
まとめ
これまで紹介してきたように、Rubyのcaseは、他のプログラム言語のswitchと似ていますが、同じものではありません。正規表現や配列が扱えるなど、オブジェクト指向言語のRubyらしい使い方ができるメソッドの一つです。
新しい機能をプログラムで実現する場合、そのプログラムの書き方は一つではありません。とはいっても、Rubyのプログラムで実現するのなら、Rubyらしい書き方を使えば、簡潔に読みやすいプログラムを作れます。そういったプログラムを書くために、splitメソッドをうまく活用してください。