Class: RuboCop::Cop::Performance::ChainArrayAllocation
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Performance::ChainArrayAllocation
- 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 collapse
- 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
- RETURNS_NEW_ARRAY_WHEN_NO_BLOCK =
These methods return a new array only when called without a block.
%i[zip product].to_set.freeze
- 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
- RETURNS_NEW_ARRAY =
(ALWAYS_RETURNS_NEW_ARRAY + RETURNS_NEW_ARRAY_WHEN_NO_BLOCK).freeze
- MSG =
'Use unchained `%<method>s` and `%<second_method>s!` ' \ '(followed by `return array` if required) instead of chaining ' \ '`%<method>s...%<second_method>s`.'
Instance Method Summary collapse
Instance Method Details
#on_send(node) ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# 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 |