Skip to content

Commit

Permalink
[Fix rubocop#437] Fix a false positive for `Performance/ChainArrayAll…
Browse files Browse the repository at this point in the history
…ocation`

Fixes rubocop#437.

This PR fixes a false positive for `Performance/ChainArrayAllocation`
when using `select` with block argument after `select`.
  • Loading branch information
koic committed Jan 31, 2024
1 parent 3ba5d91 commit 7bd4307
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#437](https://github.com/rubocop/rubocop-performance/issues/437): Fix a false positive for `Performance/ChainArrayAllocation` when using `select` with block argument after `select`. ([@koic][])
4 changes: 4 additions & 0 deletions lib/rubocop/cop/performance/chain_array_allocation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ def on_send(node)
chain_array_allocation?(node) do |fm, sm|
return if node.each_descendant(:send).any? { |descendant| descendant.method?(:lazy) }

# NOTE: `QueryMethods#select` in Rails accepts positional arguments, whereas `Enumerable#select` does not.
# This difference can be utilized to reduce the knowledge requirements related to `select`.
return if node.method?(:select) && node.arguments.any?

range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos)

add_offense(range, message: format(MSG, method: fm, second_method: sm))
Expand Down
17 changes: 17 additions & 0 deletions spec/rubocop/cop/performance/chain_array_allocation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,21 @@
RUBY
end
end

describe 'when using `select` with block argument after `select`' do
it 'registers an offense' do
expect_offense(<<~RUBY)
model.select(:foo, :bar).select { |item| item.do_something }
^^^^^^^ Use unchained `select` and `select!` (followed by `return array` if required) instead of chaining `select...select`.
RUBY
end
end

describe 'when using `select` with positional arguments after `select`' do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
model.select(:foo, :bar).select(:baz, :qux)
RUBY
end
end
end

0 comments on commit 7bd4307

Please sign in to comment.