カテゴリ: Ruby 更新日: 2026/01/28

Rubyのパターンマッチとハッシュを徹底解説!case inとキーワード引数の連携

パターンマッチとHash:case in・キーワード引数との連携
パターンマッチとHash:case in・キーワード引数との連携

先生と生徒の会話形式で理解しよう

生徒

「ハッシュの中身が特定の形かどうかを、もっとスマートに調べる方法はありますか?」

先生

「それなら『パターンマッチ』という機能がぴったりですよ。case文とinを使うと、データの形をパズルみたいに照合できるんです。」

生徒

「パズルみたいに?難しそうですが、初心者でも使いこなせますか?」

先生

「もちろんです!メソッドの引数と組み合わせる方法など、便利な使い方を一緒に見ていきましょう。」

1. パターンマッチとは?データの「形」をチェックする魔法

1. パターンマッチとは?データの「形」をチェックする魔法
1. パターンマッチとは?データの「形」をチェックする魔法

Rubyのプログラミングにおいて、パターンマッチは比較的新しく追加された非常に強力な機能です。これまでのプログラミングでは、「この箱の中身は10かな?」というように、値そのものを一つずつ確認するのが一般的でした。

しかし、パターンマッチを使うと、「このハッシュには『名前』と『年齢』がちゃんと入っているかな?」というように、データの構造(形)をまるごとチェックすることができます。これは、複雑な情報を整理して扱うときにとても役立ちます。パソコンを触ったことがない方でも、バラバラに届いた荷物を、宛先や中身の種類ごとに自動で仕分けするベルトコンベアをイメージすると分かりやすいかもしれません。

特にハッシュ(Hash)との相性が抜群で、特定のキーが存在するかどうかを確認しながら、その値をそのまま変数に取り出すといった離れ業が簡単にできるようになります。

2. case in文の基本:ハッシュの構造を判定する

2. case in文の基本:ハッシュの構造を判定する
2. case in文の基本:ハッシュの構造を判定する

パターンマッチを行うには、caseinという言葉を組み合わせて使います。従来のcase whenによく似ていますが、inを使うことで「構造の照合」が可能になります。

まずは、簡単な例を見てみましょう。ユーザーの情報が入ったハッシュが、特定の条件を満たしているかを判定します。


user = { name: "田中", age: 25 }

case user
in { name: n, age: 20..29 }
  puts "#{n}さんは20代です。"
in { name: n, age: 30..39 }
  puts "#{n}さんは30代です。"
else
  puts "その他の世代です。"
end

このコードでは、userというハッシュの中にnameというキーがあるか、そしてageが20代の範囲内にあるかを一度に調べています。注目すべきは、name: nと書くことで、ハッシュの中身を自動的にnという新しい変数に代入してくれている点です。これを分割代入と呼び、コードを劇的に短く読みやすくしてくれます。

3. 厳密な一致と部分的な一致:ピン演算子とは?

3. 厳密な一致と部分的な一致:ピン演算子とは?
3. 厳密な一致と部分的な一致:ピン演算子とは?

パターンマッチを使っていると、「変数の中身と同じ値であること」を確認したい場面が出てきます。その時に使うのが、ピン演算子(^)です。ハットのような記号ですね。

通常、パターンマッチの中で変数名を書くと「新しい変数として代入する」という意味になってしまいますが、^を頭に付けることで「すでにあるこの変数の値と一致するか確認してね!」という指示に変わります。


target_name = "佐藤"
data = { name: "佐藤", status: "ログイン中" }

case data
in { name: ^target_name, status: s }
  puts "#{target_name}さんは現在#{s}です。"
else
  puts "対象のユーザーではありません。"
end

このように、特定の値を指定して検索したい場合にピン演算子は欠かせません。条件分岐の精度を上げるための大切なテクニックです。

4. キーワード引数とハッシュの深い関係

4. キーワード引数とハッシュの深い関係
4. キーワード引数とハッシュの深い関係

Rubyのメソッド(処理のまとまり)には、キーワード引数という便利な機能があります。これは、メソッドを呼び出すときに(name: "田中", age: 25)のように、名前を付けて値を渡す仕組みのことです。

実は、このキーワード引数は内部的にはハッシュのような振る舞いをしています。そのため、パターンマッチの考え方を応用することで、メソッドに渡された複雑な設定情報をスマートに処理することができるようになります。引数が多いメソッドを作る際、一つひとつの値をif文でチェックするのは大変ですが、パターンマッチなら一瞬です。

5. メソッド内でのパターンマッチ活用例

5. メソッド内でのパターンマッチ活用例
5. メソッド内でのパターンマッチ活用例

実際に、メソッドの中でハッシュを受け取り、パターンマッチを使って処理を分けるコードを書いてみましょう。例えば、商品の発送情報を処理するプログラムを考えてみます。


def process_order(order)
  case order
  in { category: "食品", price: p } if p > 5000
    puts "高級食品の注文です。冷蔵便で送ります。"
  in { category: "食品", price: p }
    puts "食品の注文です。通常便で送ります。"
  in { category: "雑貨" }
    puts "雑貨の注文です。メール便で送ります。"
  else
    puts "不明な注文内容です。"
  end
end

process_order({ category: "食品", price: 6000 })
process_order({ category: "雑貨" })

ここで使っているif p > 5000という部分は、ガード条件と呼ばれます。パターンが一致した上で、さらに細かい条件(5000円より高いかどうか)をチェックしたい時に使います。まるで熟練の仕分け作業員のような、きめ細やかな処理が可能になります。

6. 配列とハッシュが混ざった複雑なデータへの挑戦

6. 配列とハッシュが混ざった複雑なデータへの挑戦
6. 配列とハッシュが混ざった複雑なデータへの挑戦

実際の開発では、ハッシュの中に配列が入っていたり、その逆だったりと、データが複雑な入れ子構造になっていることがよくあります。これをプログラミング未経験の方が手作業で分解しようとすると、パニックになってしまうかもしれません。

しかし、パターンマッチなら、その見た目のままをinの後に書くだけで中身を取り出せます。例えば、「複数のSNSアカウント情報を持つユーザー」という複雑なデータを見てみましょう。


user_data = {
  name: "鈴木",
  sns: ["Twitter", "Instagram"]
}

case user_data
in { name: n, sns: [first_sns, *others] }
  puts "#{n}さんのメインSNSは#{first_sns}です。"
  puts "他にも#{others.length}個のアカウントがあります。"
end

鈴木さんのメインSNSはTwitterです。
他にも1個のアカウントがあります。

[first_sns, *others]という書き方は、「最初の一個を取り出して、残りは全部othersというリストに入れてね」という意味です。これを可変長パターンなどと呼びます。複雑なデータも、まるでパズルを解くように楽しく扱えるようになりますね。

7. 安全なプログラムのために:パターンマッチの注意点

7. 安全なプログラムのために:パターンマッチの注意点
7. 安全なプログラムのために:パターンマッチの注意点

パターンマッチは非常に便利ですが、一つだけ注意点があります。それは、case inを使った場合、どのパターンにも一致しないとエラーが発生してプログラムが止まってしまうという点です。これを避けるために、記事の後半でも使ったように、最後に必ずelseを用意しておくか、どんな形でも受け入れる「ワイルドカード」的なパターンを用意するのが安全設計のコツです。

また、ハッシュを対象にする場合は、指定したキー以外が含まれていても一致とみなされます(部分一致)。逆に、配列を対象にする場合は要素の数がぴったり合っていないと一致しません。この「ハッシュは少し寛大、配列は厳格」という性格の違いを覚えておくと、バグの少ないスムーズな開発ができるようになります。

Rubyのパターンマッチとハッシュを組み合わせることで、あなたのプログラムはより読みやすく、そして力強いものへと進化します。最初は難しく感じるかもしれませんが、まずは簡単なデータの仕分けから試してみてくださいね!

カテゴリの一覧へ
新着記事
New1
Ruby
Rubyプログラムの実行方法まとめ:スクリプト・REPL・Shebang・実行権限の基本
New2
Rails
アセットの全体像をやさしく解説!importmap・jsbundling・cssbundlingの選び方
New3
Rails
Rails Action Cable入門|チャネル・接続・サブスクライブの基本を図解でやさしく解説
New4
Rails
RailsのScaffoldは使うべき?初心者向けにメリット・デメリット・安全な使い方と代替案を解説!
人気記事
No.1
Java&Spring記事人気No1
Ruby
Rubyのreduceとinject入門!合計計算や集計を初心者向けに分かりやすく解説
No.2
Java&Spring記事人気No2
Ruby
Rubyの文字列エンコーディング完全ガイド!Encoding・force_encoding・encodeを初心者向け解説
No.3
Java&Spring記事人気No3
データベース
PostgreSQLのWHERE句を徹底解説!初心者でもわかるSQLデータ抽出の基本
No.4
Java&Spring記事人気No4
Rails
Rails認可をやさしく理解!CanCanCan入門:ability.rbの定義とload_and_authorize_resource実例
No.5
Java&Spring記事人気No5
Ruby
Rubyで比較演算子を完全解説!==・===・<=>・eql? の使い分け
No.6
Java&Spring記事人気No6
Ruby
OpenSSL関連エラーの直し方を完全解説!証明書・ビルドオプション・brew対策まとめ
No.7
Java&Spring記事人気No7
データベース
MySQLとは?初心者向けにデータベースの特徴とできることをやさしく解説
No.8
Java&Spring記事人気No8
データベース
PostgreSQLのCTE(WITH句)完全解説!複雑なSQLを整理して読みやすくする書き方