case value
=> pat [if|unless cond]
...
=> pat [if|unless cond]
...
else
...
end
pat: var # 任意のオブジェクトにマッチし、varを束縛
| _ # 任意のオブジェクト
| literal # ===メソッドの実行結果が真になるオブジェクト
| Constant # 同上
| var_ # 同上(Elixirのピン演算子相当)
| [pat, ..., *var, pat, ...] # 配列
| {id:, id: pat, literal => pat, ..., **var} # ハッシュ
| var(pat, ...) | Constant(pat, ...) # ScalaのExtractor相当
| /re/(pat, ...) # 同上
| !pat # patにマッチしないか
| pat && pat # 両方のpatにマッチするか
| pat || pat # どちらかのpatにマッチするか
class EMail
def self.deconstruct(value)
parts = value.to_s.split(/@/)
if parts.length == 2
parts
else
raise PatternNotMatch
end
end
end
x_ = 'bar'
case {a: ['foo-bar@example.com', 'baz-bar@example.com'], b: ['hoge@example.com'], c: ['piyo@example.com']}
=> {a: [_, *ary, mail && EMail(name && /(\w+)-(\w+)/(firstname, x_), domain)],
b:, **h}
p mail #=> "baz-bar@example.com"
p name #=> "baz-bar"
p firstname #=> "baz"
p domain #=> "example.com"
p b #=> ["hoge@example.com"]
p ary #=> []
p h #=> {:c=>["piyo@example.com"]}
end
https://github.com/k-tsj/ruby/tree/prototype-pattern-matching