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. Giving the intermediate results descriptive names (or extracting a method) almost always reads better and is easier to debug than peeling parentheses apart. The point is not the assignment but the name: it should say what the value is, so the step documents itself.

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 - a name that documents what the value is
parsed_config = parse(read(io))
wrap(parsed_config)

# 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



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

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:, max:)) do
    self.max = depth
  end
end