collect
Collectとは
collect とは、フィルタで値のリストを得ることに特化した機能です。
Plugin.filtering
でイベントのフィルタだけを呼び出すことができます。イベントがキューに積まれて後で実行されるのに対して、 Plugin.filtering
はフィルタをその場で呼び出して、メソッドの戻り値として引数をフィルタした結果を返します。
以下は、従来のフィルタのおさらいです。
filter_mute do |world, yielder|
if world == 'hoge'
yielder << 'toshi_a'
end
[yielder]
end
このようなフィルタは、第二引数に <<
メソッドで値を挿入することで、複数のプラグインが :mute
イベントの結果に値を加えることができるのでした。
filter_mute do |world, yielder|
yielder << 'jack'
[yielder]
end
world, users = Plugin.filtering(:mute, 'hoge', [])
world # => "hoge"
users # => ["toshi_a", "jack"]
world, users = Plugin.filtering(:mute, 'fuga', [])
world # => "fuga"
users # => ["jack"]
Collectが解決すること
collectは単純なフィルタの定義はそのままで、従来のフィルタ戻り値の受け取り方のコードを簡潔にすることを目的とします。以下が、従来のフィルタ戻り値の受け取り方をcollectを使って書き換えたものです。
collect(:mute, 'hoge') # => ["toshi_a", "jack"]
collect(:mute, 'fuga') # => ["jack"]
関心のある値だけを取得できる
Plugin.filtering
は、引数全てを配列にして戻り値とします。あるフィルタの引数として5つの引数が必要なら、 Plugin.filtering
の戻り値は5要素の配列です。したがって単純なフィルタの定義のように多重代入で必要な要素だけピックアップするか、 Plugin.filtering(…)[1]
のように書いていました。
一方、collectはコレクション引数のみを返します。コレクションフィルタの戻り値では、コレクション引数にしか興味がないことがほとんどなので、些細なことですがこの挙動は非常に有用です。
Collectionとのシナジー
collectは従来のフィルタ戻り値の受け取り方のようなコードを簡潔にすることを目的としていると説明しましたが、単純なフィルタの定義を改善するのはCollectionです。
collectは従来のフィルタと互換性がある一方で、Collectionといっしょに使うことでパフォーマンスが有利になります。
collect
コレクションフィルタの定義
defevent :mute, prototype: [String, Pluggaloid::COLLECT]
defevent
でイベントを定義するとき、 prototype:
キーワード引数に渡す配列の中に、 Pluggaloid::COLLECT
という定数を含めると、コレクションフィルタになります。