class RuboCop::Cop::Lint::UnexpectedBlockArity

Checks for a block that is known to need more positional block arguments than are given (by default this is configured for ‘Enumerable` methods needing 2 arguments). Optional arguments are allowed, although they don’t generally make sense as the default value will be used. Blocks that have no receiver, or take splatted arguments (ie. ‘*args`) are always accepted.

Keyword arguments (including ‘**kwargs`) do not get counted towards this, as they are not used by the methods in question.

Method names and their expected arity can be configured like this:

source,yaml

Methods:

inject: 2
reduce: 2

@safety

This cop matches for method names only and hence cannot tell apart
methods with same name in different classes, which may lead to a
false positive.

@example

# bad
values.reduce {}
values.min { |a| a }
values.sort { |a; b| a + b }

# good
values.reduce { |memo, obj| memo << obj }
values.min { |a, b| a <=> b }
values.sort { |*x| x[0] <=> x[1] }

Constants

MSG

Public Instance Methods

on_block(node) click to toggle source
# File lib/rubocop/cop/lint/unexpected_block_arity.rb, line 44
def on_block(node)
  return if acceptable?(node)

  expected = expected_arity(node.method_name)
  actual = arg_count(node)
  return if actual >= expected

  message = format(MSG, method: node.method_name, expected: expected, actual: actual)
  add_offense(node, message: message)
end
Also aliased as: on_numblock
on_numblock(node)
Alias for: on_block

Private Instance Methods

acceptable?(node) click to toggle source
# File lib/rubocop/cop/lint/unexpected_block_arity.rb, line 63
def acceptable?(node)
  !(included_method?(node.method_name) && node.receiver)
end
arg_count(node) click to toggle source
# File lib/rubocop/cop/lint/unexpected_block_arity.rb, line 75
def arg_count(node)
  return node.children[1] if node.numblock_type? # the maximum numbered param for the block

  # Only `arg`, `optarg` and `mlhs` (destructuring) count as arguments that
  # can be used. Keyword arguments are not used for these methods so are
  # ignored.
  node.arguments.count do |arg|
    return Float::INFINITY if arg.restarg_type?

    arg.arg_type? || arg.optarg_type? || arg.mlhs_type?
  end
end
expected_arity(method) click to toggle source
# File lib/rubocop/cop/lint/unexpected_block_arity.rb, line 71
def expected_arity(method)
  cop_config['Methods'][method.to_s]
end
included_method?(name) click to toggle source
# File lib/rubocop/cop/lint/unexpected_block_arity.rb, line 67
def included_method?(name)
  methods.key?(name.to_s)
end
methods() click to toggle source
# File lib/rubocop/cop/lint/unexpected_block_arity.rb, line 59
def methods
  cop_config.fetch('Methods', [])
end