Rubyのパターンマッチ(case in)入門!配列・ハッシュの分解からガード句まで徹底解説
生徒
「Rubyで、複雑なデータの中身をチェックして、ついでに中身を取り出す簡単な方法はありますか?」
先生
「それなら、パターンマッチという機能がぴったりですよ。case文と似ていますが、もっと強力です。」
生徒
「パターンマッチですか。難しそうですが、私のような初心者でも大丈夫でしょうか?」
先生
「大丈夫です!形を合わせるパズルだと思えば分かりやすいですよ。一緒に見ていきましょう!」
1. パターンマッチとは?データの「形」で条件分岐する最新機能
Rubyのパターンマッチは、比較的新しいバージョンで導入された、とても便利な条件分岐の仕組みです。これまでのif文やcase when文は、主に「値が同じかどうか」を調べていました。しかし、パターンマッチは「データの構造(形)が合っているか」をチェックします。
例えば、箱の中に「名前」と「年齢」が書いてあるカードが入っているとします。パターンマッチを使えば、「名前が書いてあるカードかな?」と形を確認しながら、その「名前」という中身をそのまま取り出して、すぐにプログラムで使えるようにしてくれます。これを分解と呼びます。プログラミング未経験の方でも、形を合わせる型はめパズルをイメージすれば、その便利さが伝わるはずです。
Rubyの文法を基礎からしっかり固めたい人や、 現場で役立つ「テスト駆動開発」の考え方まで身につけたい人には、 評価の高いこの一冊がおすすめです。
プロを目指す人のためのRuby入門をAmazonで見る※ Amazon広告リンク
2. 配列のパターンマッチ!中身を順番に取り出す方法
まずは、複数のデータが順番に並んだ配列(はいれつ)を使ったパターンマッチを見てみましょう。配列とは、電車の車両のようにデータが連結されているものです。これまでは、1番目のデータ、2番目のデータと個別に指定して取り出す必要がありました。
パターンマッチ(case in)を使えば、その配列がどのような構成になっているかを指定するだけで、変数に中身を自動で割り当ててくれます。以下の例では、[1, 2, 3]という配列が、指定した形と一致するかを調べています。一致した瞬間に、中身を変数として使えるようになるのが魔法のようなポイントです。
data = [10, 20]
case data
in [a, b]
puts "最初の値は#{a}で、次の値は#{b}です"
else
puts "形が合いませんでした"
end
最初の値は10で、次の値は20です
3. ハッシュのパターンマッチ!特定の鍵を探して分解
次に、名前と値がセットになったハッシュ(Hash)というデータの塊を扱ってみましょう。ハッシュは、住所録のように「氏名:山田」「年齢:20」といった形式で管理されるデータです。これをパターンマッチで扱うと、特定のラベル(鍵)がついた中身だけをピンポイントで取り出すことができます。
この機能の凄いところは、全ての項目を書かなくても、自分が必要なラベルだけを指定して合致させることができる点です。パソコンに慣れていない方でも、大量の書類の中から特定のハンコが押してある場所だけを探し出し、その横に書いてある文字を書き写す作業を自動化していると思えば分かりやすいでしょう。非常にスッキリとしたコードになります。
user = {name: "田中", age: 30, city: "東京"}
case user
in {name: n, age: a}
puts "お名前は#{n}さん、年齢は#{a}歳ですね"
else
puts "データが不足しています"
end
お名前は田中さん、年齢は30歳ですね
4. 型(クラス)によるチェック!中身が何かを厳密に調べる
パターンマッチでは、データの形だけでなく、そのデータがそもそも「何の種類のデータか」という型(クラス)も一緒にチェックできます。例えば、数字のつもりで扱っていたデータが実は文字だった、という間違いはプログラミングでよくある失敗です。
変数名: クラス名 という形式で指定することで、「このデータは整数(Integer)であるべきだ」といった条件を付けることができます。これにより、意図しないデータが入ってきたときにプログラムが壊れるのを防ぐことができ、より信頼性の高い、頑丈な仕組みを作ることが可能になります。初心者こそ、この型の意識を持つことが大切です。
5. ガード句(if)でさらに細かい条件を付け加える
「形は合っているけれど、中身が特定の条件を満たすときだけ処理したい」という場合には、ガード句(if)を使います。これは、パターンに合致したあとに、さらに追加でテストを行うようなイメージです。例えば、「配列の形は[a, b]だけど、aが100以上のときだけ特別扱いしたい」という場合です。
使い方は簡単で、パターンの後ろに if 条件 を書き足すだけです。このガード句を使いこなすことで、複雑な条件分岐を非常にシンプルに表現できるようになります。日常生活で例えるなら、書類の形式が正しいことを確認した上で、「さらに金額が予算内かどうかもチェックする」という二段構えの確認作業に似ています。
score = [85, 90]
case score
in [math, english] if math >= 80
puts "数学が優秀です!点数は#{math}点です"
in [math, english]
puts "合計点は#{math + english}点です"
end
数学が優秀です!点数は85点です
6. 入れ子(ネスト)構造のデータを一気に分解する
実際のプログラムでは、ハッシュの中に配列が入っていたり、その逆だったりと、複雑に積み重なった入れ子(ネスト)構造のデータがよく登場します。これまでの方法だと、何回も中身を取り出す作業を繰り返さなければなりませんでした。
パターンマッチの真骨頂は、このような深い階層にあるデータも一撃で取り出せることです。形さえ指定すれば、一番深いところにある宝箱の鍵を一度に開けて中身を取り出すことができます。これは他のプログラミング言語にはなかなかないRubyの強力な武器の一つです。初心者の方は、この書き方を知っておくだけで、複雑なデータ処理に怯える必要がなくなります。
7. アンダースコア(_)で不要なデータを読み飛ばす
データの形は決まっているけれど、特定の部分には興味がない、というときもあります。例えば、3つの要素がある配列のうち、真ん中のデータだけ使わないといったケースです。そんなときはアンダースコア(_)を使います。これは「ここはどんな値でもいいし、無視するよ」という意味の特殊な記号です。
全てに名前をつける必要がないため、コードが読みやすくなり、他のプログラマー(あるいは未来の自分)に「このデータは使っていないよ」と伝える重要なサインにもなります。パソコン操作で言えば、不要な通知をオフにして必要な情報だけに集中するような、スマートなやり方です。無駄な変数を増やさないことは、良いプログラムを書くための基本です。
location = ["東京", "港区", "123-4567"]
case location
in [city, _, zip]
puts "都市名は#{city}で、郵便番号は#{zip}です"
else
puts "住所の形式が正しくありません"
end
都市名は東京で、郵便番号は123-4567です
8. 厳密な一致を求める!ピン演算子(^)の活用
パターンマッチの中で、既にある変数の値と同じかどうかを調べたいときには、ピン演算子(^)を使います。これを使わないと、パターンマッチはその場所を新しい変数の定義だと思い込んで上書きしてしまいます。既に決まっている正解と、届いたデータを照らし合わせるための「固定ピン」だと思ってください。
例えば、秘密の合言葉を変数に保存しておき、送られてきたデータがその合言葉と一致するか確認する場合に役立ちます。このように、パターンマッチは単なる分類だけでなく、セキュリティや正確性が求められる場面でも柔軟に対応できるよう設計されています。一歩ずつ、こうした細かいテクニックを身につけていきましょう。