4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rubyのパターンマッチで遊んでみた

Last updated at Posted at 2024-11-05

はじめに

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]

:tada:

さいごに

文法になれてしまえば、Ruby でも比較的簡単にパターンマッチができることがわかりました。

複雑なロジックを簡潔で明確なコードで表現できる可能性があると思いました。

今後、さらに実践的なプログラムでも試していこうと思います。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?