Class: RuboCop::Cop::Performance::MapMethodChain

Inherits:
Base
  • Object
show all
Includes:
IgnoredNode
Defined in:
lib/rubocop/cop/performance/map_method_chain.rb

Overview

Checks if the map method is used in a chain.

Autocorrection is not supported because an appropriate block variable name cannot be determined automatically.

source,ruby

class X

def initialize
  @@num = 0
end

def foo
  @@num += 1
  self
end

def bar
  @@num * 2
end

end

X.new, X.new].map(&:foo).map(&:bar) # => [4, 4
X.new, X.new].map { |x| x.foo.bar } # => [2, 4

Examples:


# bad
array.map(&:foo).map(&:bar)

# good
array.map { |item| item.foo.bar }

Constant Summary collapse

MSG =
'Use `%<method_name>s { |x| x.%<map_args>s }` instead of `%<method_name>s` method chain.'
RESTRICT_ON_SEND =
%i[map collect].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rubocop/cop/performance/map_method_chain.rb', line 53

def on_send(node)
  return if part_of_ignored_node?(node)
  return unless (map_arg = block_pass_with_symbol_arg?(node.first_argument))

  map_args = [map_arg]

  return unless (begin_of_chained_map_method = find_begin_of_chained_map_method(node, map_args))

  range = begin_of_chained_map_method.loc.selector.begin.join(node.source_range.end)
  message = format(MSG, method_name: begin_of_chained_map_method.method_name, map_args: map_args.join('.'))

  add_offense(range, message: message)

  ignore_node(node)
end