Skip to content

Instantly share code, notes, and snippets.

@k-tsj
Last active September 25, 2016 14:06
Show Gist options
  • Save k-tsj/5e8a3167d654b04dac9231c329387928 to your computer and use it in GitHub Desktop.
Save k-tsj/5e8a3167d654b04dac9231c329387928 to your computer and use it in GitHub Desktop.

Syntax

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にマッチするか

Example

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

Patch

https://github.com/k-tsj/ruby/tree/prototype-pattern-matching

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment