Class: RuboCop::Cop::Performance::Count

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
RangeHelp
Defined in:
lib/rubocop/cop/performance/count.rb

Overview

Identifies usages of ‘count` on an `Enumerable` that follow calls to `select`, `find_all`, `filter` or `reject`. Querying logic can instead be passed to the `count` call.

Examples:

# bad
[1, 2, 3].select { |e| e > 2 }.size
[1, 2, 3].reject { |e| e > 2 }.size
[1, 2, 3].select { |e| e > 2 }.length
[1, 2, 3].reject { |e| e > 2 }.length
[1, 2, 3].select { |e| e > 2 }.count { |e| e.odd? }
[1, 2, 3].reject { |e| e > 2 }.count { |e| e.even? }
array.select(&:value).count

# good
[1, 2, 3].count { |e| e > 2 }
[1, 2, 3].count { |e| e < 2 }
[1, 2, 3].count { |e| e > 2 && e.odd? }
[1, 2, 3].count { |e| e < 2 && e.even? }
Model.select('field AS field_one').count
Model.select(:value).count

Constant Summary collapse

MSG =
'Use `count` instead of `%<selector>s...%<counter>s`.'
RESTRICT_ON_SEND =
%i[count length size].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object Also known as: on_csend



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rubocop/cop/performance/count.rb', line 62

def on_send(node)
  count_candidate?(node) do |selector_node, selector, counter|
    return unless eligible_node?(node)

    range = source_starting_at(node) do
      selector_node.loc.selector.begin_pos
    end

    add_offense(range, message: format(MSG, selector: selector, counter: counter)) do |corrector|
      autocorrect(corrector, node, selector_node, selector)
    end
  end
end