Share
Embed
パターンマッチと右代入が便利になる gem をつくった
osyo
November 05, 2020
Transcript
23 slides
-
⾃⼰紹介 ⾃⼰紹介 名前:osyo Twitter : github : ブログ : 趣味で
Ruby にパッチを投げたり bugs.ruby で気になったチケットを ブログにまとめたりしてる Ruby 2.5 〜 2.7 までオレオレ機能を追加した Ruby 3.0 では機能追加できなかった… Ruby で⼀番好きな機能は Refinements オンラインなのであちこちの地域.rb に参加してる @pink_bangbi osyo-manga Secret Garden(Instrumental) Fukuoka.rb Hamada.rb kawasaki.rb nikotama.rb Sendai.rb Shibuya.rb Shinjuku.rb Tama.rb Toyama.rb Gotanda.rb Entaku.rb Grow.rb Hamamatsu.rb kanazawa.rb Kobe.rb Machida.rb mitaka.rb Ruby Tuesday toruby ⻄⽇暮⾥.rb -
Ruby 2.7 / 3.0 でパターンマッチが⼊った Ruby 2.7 / 3.0 でパターンマッチが⼊った
Ruby 2.7 / 3.0 でパターンマッチが⼊りました これは以下のような感じで使うことができる def check(user) case user in { name:, age: (..20) } "#{name} は魔法少⼥です" in { name:, age: (20..) } "#{name} は魔法少⼥ではありません" else " わからない" end end p check({ name: " ほむ", age: 14 }) # => " ほむは魔法少⼥です" p check({ name: " マミ", age: 30 }) # => " マミは魔法少⼥ではありません" p check([" まどか", 14]) # => " わからない" -
任意のクラスでパターンマッチできる 任意のクラスでパターンマッチできる #deconstruct_keys を定義することで拡張できる class Time # in に書いた Hash
のキーを受け取る # 返した Hash でパターンマッチを⾏う def deconstruct_keys(keys) { year: year, month: month, day: day } end def to_four_seasons case self in { month: (3..5) } then "spring" in { month: (6..8) } then "summer" in { month: (9..11) } then "autumn" in { month: (1..2) } | { month: 12 } then "winter" end end end p Time.now.to_four_seasons # => "autumn" -
応⽤するとこんな事ができる 応⽤するとこんな事ができる module PatternMatchWithMethod # メソッドを呼び出すような拡張を⾏う def deconstruct_keys(keys) keys.to_h {
|name| [name, public_send(name)] } end end class Time include PatternMatchWithMethod def to_four_seasons case self in { month: (3..5) } then "spring" in { month: (6..8) } then "summer" in { month: (9..11) } then "autumn" in { month: (1..2) } | { month: 12 } then "winter" end end end p Time.now.to_four_seasons # => "autumn" -
いろいろと便利に使える class Array include PatternMatchWithMethod end # 配列のメソッドの結果を取得する case ["homu",
"mami", "mado"] in { first:, last:, size: } end p first # => "homu" p last # => "mado" p size # => 3 # インスタンスに extend して⽣やすこともできる case { name: "homu", age: 14 }.extend PatternMatchWithMethod in { keys:, values: } end p keys # => [:name, :age] p values # => ["homu", 14] -
pattern_matchable pattern_matchable require "pattern_matchable" class Time # PatternMatchable を include
するとすぐに使える include PatternMatchable def to_four_seasons case self in { month: (3..5) } then "spring" in { month: (6..8) } then "summer" in { month: (9..11) } then "autumn" in { month: (1..2) } | { month: 12 } then "winter" end end end p Time.now.to_four_seasons # => "autumn" -
using PatternMatchable するだけで拡張できる using PatternMatchable するだけで拡張できる require "pattern_matchable" # このファイル内でのみ反映される
using PatternMatchable class Time def to_four_seasons case self in { month: (3..5) } then "spring" in { month: (6..8) } then "summer" in { month: (9..11) } then "autumn" in { month: (1..2) } | { month: 12 } then "winter" end end end p Time.now.to_four_seasons # => "autumn" case ["homu", "mami", "mado"] in { first:, last:, size: } end p [first, last, size] # => ["homu", "mado", 3] -
特定のクラスのみ拡張もできる 特定のクラスのみ拡張もできる require "pattern_matchable" class Time # Time クラスのみ拡張する using
PatternMatchable Time def to_four_seasons case self in { month: (3..5) } then "spring" in { month: (6..8) } then "summer" in { month: (9..11) } then "autumn" in { month: (1..2) } | { month: 12 } then "winter" end end end p Time.now.to_four_seasons # => "autumn" # Array は拡張されない # error: ["homu", "mami", "mado"] (NoMatchingPatternError) case ["homu", "mami", "mado"] -
右代⼊ 右代⼊ Ruby 3.0 で右代⼊が⼊る予定 これは左辺の値を右辺の変数に代⼊する構⽂ また以下のような機能も⼊る予定 これって分割代⼊じゃね? これって分割代⼊じゃね? result
= 42 # を 42 => result user = { name: "homu", age: 14 } case user in { name:, age: } end # を user => { name:, age: } p [name, age] # => ["homu", 14] -
ちなみにパターンマッチなので以下のように書くこともできる homu = { name: "homu", age: 14 } #
特定のクラスのみ代⼊できる homu => { name: String => name, age: Integer => age } p [name, age] # => ["homu", 14] mami = { name: :mami, age: 14 } # これはエラー # error: {:name=>:mami, :age=>14} (NoMatchingPatternError) mami => { name: String => name, age: Integer => age } p [name, age] # => ["homu", 14] -
まとめ まとめ Ruby 2.7 / 3.0 でパターンマッチという機能が実装された パターンマッチ便利 パターンマッチは #deconstruct_keys
を定義することで任意のクラス をパターンマッチすることができる を使うと簡単に既存のクラスを拡張できるよ Refinements は最⾼だな!! 右代⼊も最⾼だな!! pattern_matchable -
宣伝 宣伝 今週の⾦曜⽇だよ! yukicoder の問題をみんなで解いてみるよ! 今年もやるよ!!! みんな参加してね! Ruby 3.0 についての
Advent Calendar だよ!!! 寂しいのでみんな参加してね!! 参加して!!! Machida.rb #07 - Machida.rb | Doorkeeper Ruby Advent Calendar 2020 Ruby 3.0 Advent Calendar 2020 令和時代の基礎⽂法最速マスター