Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pattern Matching in Ruby

k_tsj
September 15, 2012

Pattern Matching in Ruby

k_tsj

September 15, 2012
Tweet

More Decks by k_tsj

Other Decks in Programming

Transcript

  1. 新しい人参が必要 • Multiple VM • JIT • 世代別/並列GC • …

    • パターンマッチ We need a new carrot Generational/Parallel GC Pattern matching
  2. ?

  3. 比較 a, (b, c) = [1, [2, 3]] Array(1, Array(2,

    3)) match { case Array(a, Array(b, c)) => ... } Comparing 多重代入 Multiple assignment パターンマッチ Pattern matching
  4. 多重代入の問題点 a, (b, c), d = [1, [2, 3]] d

    #=> nil Problems of multiple assignment 2. 個数の確認等ができない Can not check number of items,etc
  5. 多重代入の問題点 a, (b, c) = [1, [2, 3]] これが欲しい Problems

    of multiple assignment Need it 3. 途中の値が代入できない Can not assign nonterminal value
  6. パターンマッチとは (多重代入 + α) + case 分解 + 代入 照合

    Deconstructuring Assignment Matching Multiple assignment What is pattern matching
  7. 他言語のパターンマッチ Language Support Type Paradigm Python Dynamic OOP Scheme (Library)

    Dynamic FP Java Static OOP Scala Static OOP+FP Haskell Static FP F# Static FP (C) 2012 Yusuke Kamiyamane. All rights reserved. / Fugue Icons Pattern matching in other languages OOP: オブジェクト指向プログラミング FP: 関数型プログラミング
  8. 基本的な使い方 Array(1, Array(2, 3)) match { case Array(a, Array(b, c))

    => Array(a, b, c) case _ => null } // => Array(1, 2, 3) Basic usage
  9. 分解 • ArrayをArrayとして Array(1, Array(2, 3)) match { case Array(a,

    Array(b, c)) => ... } Deconstructuring Array as Array
  10. 分解 • ListをListとして List(1, List(2, 3)) match { case List(a,

    List(b, c)) => ... } Deconstructuring List as List
  11. 分解 • StringをEMailとして "[email protected]" match { case EMail(user, domain) =>

    (user, domain) } //=> ("foo", "example.com") String as EMail Deconstructuring
  12. 分解 • StringをEMailとして "invalid e-mail address" match { case EMail(user,

    domain) => (user, domain) } //=> MatchError String as EMail Deconstructuring
  13. 分解 • StringをEMailとして object EMail { def unapply(str: String): Option[(String,

    String)] = { val parts = str split "@" if (parts.length == 2) Some(parts(0), parts(1)) else None } } String as EMail Deconstructuring
  14. 分解 val re = """(¥d+)-(¥d+)-(¥d+)""".r // 正規表現オブジェクトの生成 "2012-09-15" match {

    case re(yyyy, mm, dd) => (yyyy, mm, dd) } // => ("2012", "09", "15") // Create a Regex object Deconstructuring
  15. 照合 Array(1, Array(2, 3)) match { case Array(a, Array(b, c),

    d) => null case Array(a, List(b, c)) => null case Array(0, Array(b, c)) => null } // => MatchError Matching
  16. 代入 Array(1, Array(2, 3)) match { case Array(a, d @

    Array(b, c)) => Array(a, b, c, d) } // => Array(1, 2, 3, Array(2, 3)) Assignment
  17. 基本的な使い方 require 'pattern-match' match([0, [1, 2]]) { with(Array.(a, Array.(b, 2))

    { [a, b] #=> [0, 1] } with(_[a, _[b, 2]]) { # 上記と同様 ... } } Same as above Basic usage
  18. 基本的な使い方 proc = match { with(_[a, _[b, 2]]) { [a,

    b] } } proc.call([0, [1, 2]]) #=> [0, 1] 引数なし No argument Basic usage
  19. 分解 • 分解するために必要なこと – Deconstructorのクラスに Deconstructableをincludeする – Deconstructorに deconstructメソッドを定義する with(Array.(a,

    b)) Deconstructor Deconstructuring What you need to deconstruct an object Include Deconstructable in a class of Deconstructor Define deconstruct method for Deconstructor
  20. 分解 class Regexp include PatternMatch::Deconstructable def deconstruct(val) m = Regexp.new("¥¥A#{source}¥¥z",

    options).match(val.to_s) raise PatternNotMatch unless m m.captures.empty? ? [m[0]] : m.captures end end Deconstructuring
  21. 照合/代入 match([0, [1, 2]]) { with(_[a, _[b, c], d]) =>

    nil with(_[a, List.(b, c)]) => nil with(_[1, _[b, c]]) => nil } #=> NoMatchingPatternError Matching/Assignment
  22. 照合/代入 • オブジェクトの比較は#=== match([0, 1]) { with(_[Fixnum, 1..10]) { true

    } with(_) { false } } #=> true Matching/Assignment Compare objects by #===
  23. 照合/代入 • 繰り返し match([[0, 1], [2, 3]]) { with(_[_[a, b],

    ___]) { [a, b] #=> [[0, 2], [1, 3]] } } Matching/Assignment Repetition
  24. 照合/代入 • 繰り返し match([[0, 1], [2, 3]]) { with(_[*_[a, b]])

    { [a, b] #=> [[0, 2], [1, 3]] } } Matching/Assignment Repetition
  25. 照合/代入 • Hash.() –Destructuring Assignment(#6414) john = {name: "John", last:

    "Smith"} {name: n, last: l} = john n // => "John" l // => "Smith" Matching/Assignment
  26. 照合/代入 • Hash.() –Destructuring Assignment(#6414) match({name: "John", last: "Smith"}) {

    with(Hash.(name: n, last: l)) { n #=> "John" l #=> "Smith" } } Matching/Assignment
  27. 照合/代入 • Object.() –Duck typing style match(10) { with(Object.(:to_i =>

    i, :to_s.(16) => s)) { [i, s] #=> [10, "a"] } } Matching/Assignment
  28. 利用例(テキスト処理) birthday,fullname 2012/4/1,John Smith 2011/6/3,Jane Smith 2012/9/15,Pater Smith 2012/5/22,Mary Smith

    Year: 2012 Month: 1 - 6 Month: 4, Name: John, Last: Smith Month: 5, Name: Mary, Last: Smith Examples(Text processing) 入力 Input 出力 Output
  29. 利用例(テキスト処理) • パターンマッチあり ARGF.each(&match { with(CSV.(Date.(2012, mm & 1..6, _),

    /(¥w+) (¥w+)/.(name, last))) { ... } with(_) { ... } }) Examples(Text processing) With pattern matching
  30. 利用例(テキスト処理) • パターンマッチなし ARGF.each do |i| cols = CSV.parse_line(i) if

    cols.length == 2 date = Date.parse(cols[0]) rescue nil m = cols[1].match(/(¥w+) (¥w+)/) if date and date.year == 2012 and (1..6).includes?(date.month) and m mm = date.month name, last = m.captures ... Examples(Text processing) Without pattern matching
  31. デザイン(分解) • コンテキストに応じた分解 Time.gm(year, mon = 1, day = 1,

    hour = 0, min = 0, sec = 0, usec = 0) Time.(year, mon, day, hour, min, sec, usec) Time.(year, mon, day) Time.(hour, min, sec, usec) Design(Deconstructuring) Contextual deconstructuring
  32. デザイン(照合) • 正規表現 match(["a", "b", 0, "c", "d"]) { with(_[*i,

    Fixnum, *j]) { [i, j] #=> [["a", "b"], ["c", "d"]] } } Design(Matching) Regular expression
  33. デザイン(照合) • Mathematicaの例 Replace[{1, {2, 3}}, (* List *) {a_,

    {b_, c_}} -> (* Pattern *) {a, b, c}] (* {1, 2, 3} *) Design(Matching) Examples of Mathematica
  34. デザイン(照合) • Mathematicaの例 Replace[{1, 2, 3, 4, 5}, {a___, b_,

    Shortest[c___]} -> {a}] (* {1, 2, 3, 4} *) Design(Matching) Examples of Mathematica
  35. デザイン(照合) • Mathematicaの例 Replace[{1, 2, 3, 4, 5}, {a___, b_,

    c___}/;b>2 -> {a}] (* {1, 2} *) Design(Matching) Examples of Mathematica
  36. デザイン(照合) • Setなどに対する照合 match(Set[1, 2, 3]) { with(Set.( ??? ))

    { ... } } Design(Matching) Matching against data structures like Set