Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyのcaseステートメントの多彩な活用法と仕組みを徹底解説

Rubyでif / elsifを使おうとしている場面では、代わりにcaseステートメントを使うことを検討してみてください。この記事では、caseステートメントのさまざまな活用例と、その内部で実際にどのような仕組みで動作しているのかを解説します。

Rubyのcaseステートメントの多彩な活用法と仕組みを徹底解説

補足:他のプログラミング言語では、これはswitch文として知られています。

Rubyにおけるcaseステートメントの構成要素は以下の通りです。

キーワード 説明
case caseステートメントの定義を開始します。処理対象となる変数を受け取ります。
when マッチ可能な各条件が、1つのwhen句に相当します。
else どの条件にも一致しなかった場合に実行されます。省略可能です。

Ruby Caseと範囲(Range)の組み合わせ

caseステートメントは、一見したところよりも柔軟性が高いのが特徴です。例えば、値がどの範囲に属するかに応じてメッセージを出し分けたい場合を見てみましょう。

case capacity
when 0
  "ガス欠です。"
when 1..20
  "タンクはほぼ空です。急いでガソリンスタンドを探しましょう!"
when 21..70
  "今のところは問題ありません。"
when 71..100
  "タンクはほぼ満タンです。"
else
  "エラー:capacityの値が不正です (#{capacity})"
end

if / elsifで書いた場合と比べると、このコードはかなりエレガントだと思いませんか?

Ruby Caseと正規表現(Regex)の組み合わせ

whenの条件には正規表現も使えます。次の例では、先頭の文字によって製品の危険度を示すserial_codeを判定しています。

case serial_code
when /\AC/
  "低リスク"
when /\AL/
  "中リスク"
when /\AX/
  "高リスク"
else
  "不明なリスク"
end

caseを使うべきではないケース

単純な1対1のマッピングを行いたい場合、つい次のようなコードを書きたくなるかもしれません。

case country
when "europe"
  "https://eu.example.com"
when "america"
  "https://us.example.com"
end

しかし筆者の意見としては、代わりにハッシュを使う方がおすすめです。

SITES = {
  "europe"  => "https://eu.example.com",
  "america" => "https://us.example.com"
}

SITES[country]

ハッシュを使った方法の方が効率的で、扱いやすくなります。そう思いませんか?

caseの仕組み:=== メソッドの正体

caseが内部でどのように動作しているのか気になったことはありませんか?最初の例に戻ってみると、実際には以下のような処理が行われています。

(1..20)   === capacity
(21..70)  === capacity
(71..100) === capacity

ご覧の通り、条件が左右逆になっています。これは、Rubyが左側のオブジェクトに対して===を呼び出すためです。===は単なるメソッドであり、任意のクラスで実装できます。この場合、Rangeクラスは「値が範囲内に含まれる場合のみtrueを返す」という形でこのメソッドを実装しています。

RubiniusにおけるRangeクラスの===実装は以下のようになっています。

def ===(value)
  include?(value)
end

出典:https://github.com/rubinius/rubinius/blob/master/core/range.rb#L178

ProcとCaseの組み合わせ

===を実装している興味深いクラスのもう1つが、Procクラスです。

関連記事:procとlambdaについてさらに詳しく学びましょう。

次の例では、偶数を判定するprocと奇数を判定するprocの2つを定義しています。

odd  = proc(&:odd?)
even = proc(&:even?)

case number
when odd
  puts "奇数です"
when even
  puts "偶数です"
end

実際に行われている処理は以下の通りです。

odd.===(number)
even.===(number)

procに対して===を使うことは、callを使うことと同じ効果があります。

まとめ

この記事では、Rubyのcaseステートメントの仕組みと、その高い柔軟性について学びました。ぜひご自身のプロジェクトでも、caseステートメントを効果的に活用してみてください。

この記事がお役に立てば幸いです!

より多くの人に学んでもらえるよう、ぜひシェアしてくださいね 🙂

  1. 【Ruby】デコレータデザインパターンでクラスを変更せずにオブジェクトを拡張する方法

    デコレータ(Decorator)デザインパターンとは、どのようなものなのでしょうか? また、このパターンをRubyのプロジェクトではどのように活用すればよいのでしょうか? デコレータデザインパターンを利用すると、クラスそのものを変更することなく、オブジェクトに新しい機能を追加して拡張することができます。 それでは、具体的な例を見ていきましょう! ログ出力とパフォーマンス計測の実装例 この例では、rest-clientのようなGemを使ってHTTPリクエストを送信します。 コードは次のようになります。 require restclient data = RestClient.get(www.

  2. iPhoneホームボタンの便利な使い方まとめ|基本操作から隠れた機能まで徹底解説

    iPhoneが初めて世界に登場して以来、「ホームボタン」は最も長く愛され続けてきた機能の一つです。Appleはこのボタンに数々の改良を重ねてきましたが、最新のフラッグシップモデルではついに姿を消すこととなりました。とはいえ、iPhone X以前のデバイスでは、たった一つのボタンでありながら実に多くの操作をこなせる優れものです。ホームボタンにはさまざまな使い方があり、その一部はご存じの方も多いはず。本記事では、iPhoneのホームボタンでできることをすべて一挙にご紹介します。 まずは基本!よく使われるホームボタンの操作 長押し:Siriを起動 ダブルクリック:起動中のアプリ一覧(マルチタスク