RuboCop Performance 1.11 をリリースした。主な変更点は以下。
前者はそのままなので、後者について記す。
Enumerable#filter_map
に対応づけられるのは、以下の2つの Cop となる。
これは当初 Performance/FilterMap
cop として提案していたものだが、対象となる bad ケースのコンテキストや good ケースとの互換性に違いがあるため、別々の Cop として分割した。
Performance/SelectMap
cop
この Cop は select.map
のチェーンへのケースを filter_map
に置き換えることを提示する。
# bad ary.select(&:foo).map(&:bar) ary.filter(&:foo).map(&:bar) # good ary.filter_map { |o| o.bar if o.foo }
振る舞いに互換性はあるが、good ケースの可読性について賛否があるのと、複雑なブロック処理については自動修正が困難だと思い自動修正を提供しておらず、手修正も大変そうということからデフォルトで無効にしている。
Performance/MapCompact
cop
この Cop は map.compact
のチェーンへのケースを filter_map
に置き換える。このケースは good ケースになることでコードもシンプルになると思う。
# bad ary.map(&:foo).compact ary.collect(&:foo).compact # good ary.filter_map(&:foo)
以下のいずれのケースも nil
を除外するが、filter_map
は加えて false
も除外する。このように compact
と filter_map
は振る舞いに互換性がないため、SafeAutoCorrect: false
(rubocop -A
で適用) としている。
[true, false, nil].compact #=> [true, false] [true, false, nil].filter_map(&:itself) #=> [true]
なお、Enumerable#filter_map!
というメソッドは存在しないので、以下のケースは受け入れている。
ary.map(&:foo).compact!
Performance/SelectMap
cop は好みが分かれるところだと思うが、Performance/MapCompact
cop は適用可能であれば適用しておくとコードとしてもシンプルになると思う (ただし振る舞いの違いに気をつけて適材適所で) 。
いつもの新規 Cop のようにデフォルトで pending
ステータスなので、NewCops: enable
にしているわけでなければ、以下のように有効化が必要となる。
# .rubocop.yml Performance/MapCompact: Enabled: true
今日はここまでです。ハックを続けましょう。