Class: RuboCop::Cop::Kaizo::NestedMethodCalls

Inherits:
Base
  • Object
show all
Includes:
AllowedMethods
Defined in:
lib/rubocop/cop/kaizo/nested_method_calls.rb

Overview

Checks for method calls nested too deeply in argument positions.

A call whose arguments are themselves the results of other calls -- foo(SomeClass.new(another("bar").chain)) -- packs several steps into one expression. Naming the intermediate results (or extracting a method) almost always reads better and is easier to debug than peeling parentheses apart.

Only nesting through argument positions is counted; a receiver chain such as user.account.owner.name is a separate concern. Operator methods (a + b, arr[i]) never count, and calls to AllowedMethods are exempt. Depth is measured from each outermost call and reported once. There is no autocorrection: choosing the intermediate name is a design decision.

Examples:

Max: 1 (default)

# bad
foo(SomeClass.new(another("bar").chain))

# bad
wrap(parse(read(io)))

# good - name the intermediate result
parsed = parse(read(io))
wrap(parsed)

# good - a single nested call is allowed
puts compute(value)

Constant Summary collapse

MSG =
"Avoid nesting method calls in arguments; name an intermediate " \
"result instead. [%<depth>d/%<max>d]".freeze
TRANSPARENT_ARGUMENT_TYPES =

Node types whose children sit in argument position -- looked through to reach nested calls (but never into a block body).

%i[array hash begin pair splat kwsplat].freeze

Instance Method Summary collapse

Instance Method Details

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



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rubocop/cop/kaizo/nested_method_calls.rb', line 43

def on_send(node)
  return if nested_in_call_argument?(node)
  return if allowed_method?(node.method_name)

  max = cop_config["Max"]
  depth = nesting_depth(node)
  return unless max && depth > max

  add_offense(node, message: format(MSG, depth: depth, max: max)) do
    self.max = depth
  end
end