Ruby 2.5: Enumerableの新機能: トリプルイコール`===`と述語メソッドの合わせ技(翻訳)

概要 原著者の許諾を得て翻訳・公開いたします。 英語記事: New in Enumerable — Triple Equals Predicates – Brandon Weaver – Medium 原文公開日: 2017/12/02 著者: Brandon Weaver 画像はすべて元記事からの引用です。 Ruby 2.5: Enumerableの新機能: トリプルイコール===と述語メソッドの合わせ技(翻訳) 元のIssue: #11286 [PATCH] Add case equality arity to Enumerable’s sequence predicates. 以下の素晴らしいドキュメントもご覧ください。本記事で書かれていることについて皆さまが気づかなかったことも含めてひととおり載っていて有用です。 Module: Enumerable (Ruby 2.4.2) トリプルイコール演算子の黒魔術 トリプルイコール演算子に関する以下の私の過去記事を未見の方は、ぜひお読みください。 Ruby inside: トリプルイコール === の黒魔術(翻訳) 今回の新機能についてここから先のいくつかのパラグラフでやんちゃしています。読んだ方はきっといろいろやんちゃなアイデアで心がいっぱいになることでしょう。 述語メソッド 何はともあれ、私がここで言う「述語(predicate)」が何を指すかおわかりでしょうか?ここでは、Enumerableに含まれる述語スタイルのメソッド、すなわち末尾が?のメソッドを指します。 [1,2,3].all? { |n| n.even? } # => false [2,4,6].all? { |n| n.even? } # => true [1,2,3].any? { |n| n.even? } # => true [1,3,5].any? { |n| n.even? } # => false [1,2,3].none? { |n| n.even? } # => false [1,3,5].none? { |n| n.even? } # => true これらのメソッドのショートハンドについては後述しますが、ひとまずコード例はこれを元にします。 Enumerableのgrep Enumerableにあるのに忘れられがちなメソッドのひとつに、grepがあります。 [1,2,3, ‘string’].grep(Numeric) # => [1, 2, 3] grepのドキュメントで動作を調べてみましょう。 Pattern === elementとなるすべての要素を列挙する配列を1つ返す。 トリプルイコール演算子にこんな便利な使いみちがあることはとっくにご存知かと思いますが、ひとりの勇敢なRubyistがここに少しばかり手を加える決心を固めました。 トリプルイコールに述語メソッドを食べさせる いよいよ本題です。 上述の述語系メソッドたちが「今こそ、たったひとつの引数を取って先のgrepのように===に適切に応答する時だ」と決意すると、何が起きると思いますか? マジックです。マジックが花開くのです。 %w(foo bar baz).none?(/foo/) # => false [1,2,3].all?(Numeric) # => true これはこれで面白いですが、マジックとしては小粒です。ではもう少しやってみましょうか。 %w(10.0.0.1 10.0.0.5).all?(IPAddr.new(‘10.0.0.0/8’)) システム管理者なら泣いて喜ぶところです。しかしこれだけではありません。 楽しい楽しい黒魔術 独自の===を定義する方法はもうご存知ですね?いよいよウサギの穴に飛び込むときが来ました。 ArrayやHashに機能を追加するラッパーメソッドをこしらえてみたらもっと面白くなると思いませんか?それはもう指折りの楽しさです。 ここで一言: Rubyではこの書き方はよくありません 前述の「トリプルイコール===の黒魔術」記事からコード例を再録します。 people = [ {name: ‘Bob’, age: 20}, {name: ‘Sue’, age: 30}, {name: ‘Jack’, age: 10}, {name: ‘Jill’, age: 4}, {name: ‘Jane’, age: 5} ] このデータで遊ぶには、ラッパーをこしらえておく必要があります。 class Q def initialize(conds = {}) @conds = conds end def ===(other) @conds.all? { |k, matcher| matcher === … Continue reading Ruby 2.5: Enumerableの新機能: トリプルイコール`===`と述語メソッドの合わせ技(翻訳)