はじめに
Ruby でパターンマッチができるようになったと聞いてはいましたが、まだ試したことがありませんでした。
2019 年の Ruby 2.7 の時点ですでに実験的には導入されていたのですね。
試してみます。
パターンマッチとは
公式ドキュメントに以下の通り記されています。
パターンマッチは、構造化された値に対して、構造をチェックし、マッチした部分をローカル変数に束縛するという、深いマッチを可能にする機能です。
(『束縛』は、パターンマッチの輸入元である関数型言語の用語で、Ruby では代入と読み替えても問題ありません)
関数型言語の機能を参考にして導入されたようです。ひょっとすると Elixir かもしれません。
同僚が Elixir や Rust のパターンマッチを利用してスマートに課題解決しているのをみたことがあります。
Ruby のパターンマッチで素振り
せっかくなので自分で手を動かしてみようと思います。
parse_data =
lambda do |data|
case data
in { error:, **rest }
error
in { a: { b: { status: } }, **rest }
status
in Integer => v if v.positive?
v
in [first, *rest]
rest
else
'なんじゃこれ'
end
end
p parse_data.call({ error: '失敗' })
#=> "失敗"
p parse_data.call({ a: { b: { status: '元氣' } } })
#=> "元氣"
p parse_data.call(123)
#=> 123
p parse_data.call([777, 888, 999])
#=> [888, 999]
p parse_data.call(-1)
#=> "なんじゃこれ"
Ruby のパターンマッチで Fizz Buzz
def fizz_buzz(count)
(1..count).map do |n|
case [n % 3, n % 5]
in [0, 0]
"Fizz Buzz"
in [0, _]
"Fizz"
in [_, 0]
"Buzz"
in [_, _]
n
end
end
end
fizz_buzz(16)
#=> [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "Fizz Buzz", 16]
さいごに
文法になれてしまえば、Ruby でも比較的簡単にパターンマッチができることがわかりました。
複雑なロジックを簡潔で明確なコードで表現できる可能性があると思いました。
今後、さらに実践的なプログラムでも試していこうと思います。