Class: RuboCop::Cop::Performance::ChainArrayAllocation
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Base
|
|
Instance Chain:
self,
Base
|
|
Inherits: |
Base
|
Defined in: | lib/rubocop/cop/performance/chain_array_allocation.rb |
Overview
Identifies usages of array.compact.flatten.map { |x| x.downcase }
.
Each of these methods (compact
, flatten
, map
) will generate a new intermediate array
that is promptly thrown away. Instead it is faster to mutate when we know it’s safe.
Constant Summary
-
ALWAYS_RETURNS_NEW_ARRAY =
These methods ALWAYS return a new array after they’re called it’s safe to mutate the resulting array
%i[* + - collect compact drop drop_while flatten map reject reverse rotate select shuffle sort take take_while transpose uniq values_at |].to_set.freeze
-
HAS_MUTATION_ALTERNATIVE =
These methods have a mutation alternative. For example :collect can be called as :collect!
%i[collect compact flatten map reject reverse rotate select shuffle sort uniq].to_set.freeze
-
MSG =
# File 'lib/rubocop/cop/performance/chain_array_allocation.rb', line 48'Use unchained `%<method>s` and `%<second_method>s!` ' \ '(followed by `return array` if required) instead of chaining ' \ '`%<method>s...%<second_method>s`.'
-
RETURNS_NEW_ARRAY =
# File 'lib/rubocop/cop/performance/chain_array_allocation.rb', line 46(ALWAYS_RETURNS_NEW_ARRAY + RETURNS_NEW_ARRAY_WHEN_NO_BLOCK).freeze
-
RETURNS_NEW_ARRAY_WHEN_NO_BLOCK =
These methods return a new array only when called without a block.
%i[zip product].to_set.freeze
-
RETURN_NEW_ARRAY_WHEN_ARGS =
These methods return a new array but only sometimes. They must be called with an argument. For example:
[1,2].first # => 1 [1,2].first(1) # => [1]
%i[first last pop sample shift].to_set.freeze
Instance Method Summary
Instance Method Details
#enumerable_select_method?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/performance/chain_array_allocation.rb', line 73
def enumerable_select_method?(node) # 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`. (node.block_type? || node.numblock_type?) && node.send_node.arguments.empty? end
#on_send(node)
[ GitHub ]# File 'lib/rubocop/cop/performance/chain_array_allocation.rb', line 60
def on_send(node) chain_array_allocation?(node) do |fm, sm| return if node.each_descendant(:send).any? { |descendant| descendant.method?(:lazy) } return if node.method?(:select) && !enumerable_select_method?(node.receiver) range = node.loc.selector.begin.join(node.source_range.end) add_offense(range, message: format(MSG, method: fm, second_method: sm)) end end