class RuboCop::Cop::Style::TrailingCommaInBlockArgs

Checks whether trailing commas in block arguments are required. Blocks with only one argument and a trailing comma require that comma to be present. Blocks with more than one argument never require a trailing comma.

@safety

This cop is unsafe because a trailing comma can indicate there are
more parameters that are not used.

For example:
[source,ruby]
----
# with a trailing comma
{foo: 1, bar: 2, baz: 3}.map {|key,| key }
#=> [:foo, :bar, :baz]

# without a trailing comma
{foo: 1, bar: 2, baz: 3}.map {|key| key }
#=> [[:foo, 1], [:bar, 2], [:baz, 3]]
----

This can be fixed by replacing the trailing comma with a placeholder
argument (such as `|key, _value|`).

@example

# bad
add { |foo, bar,| foo + bar }

# good
add { |foo, bar| foo + bar }

# good
add { |foo,| foo }

# good
add { foo }

# bad
add do |foo, bar,|
  foo + bar
end

# good
add do |foo, bar|
  foo + bar
end

# good
add do |foo,|
  foo
end

# good
add do
  foo + bar
end

Constants

MSG

Public Instance Methods

on_block(node) click to toggle source
# File lib/rubocop/cop/style/trailing_comma_in_block_args.rb, line 67
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
  # lambda literal (`->`) never has block arguments.
  return if node.send_node.lambda_literal?
  return unless useless_trailing_comma?(node)

  last_comma_pos = last_comma(node).pos

  add_offense(last_comma_pos) { |corrector| corrector.replace(last_comma_pos, '') }
end

Private Instance Methods

arg_count(node) click to toggle source
# File lib/rubocop/cop/style/trailing_comma_in_block_args.rb, line 83
def arg_count(node)
  node.arguments.each_descendant(:arg, :optarg, :kwoptarg).to_a.size
end
argument_tokens(node) click to toggle source
# File lib/rubocop/cop/style/trailing_comma_in_block_args.rb, line 95
def argument_tokens(node)
  tokens = processed_source.tokens_within(node)
  pipes = tokens.select { |token| token.type == :tPIPE }
  begin_pos, end_pos = pipes.map { |pipe| tokens.index(pipe) }

  tokens[begin_pos + 1..end_pos - 1]
end
last_comma(node) click to toggle source
# File lib/rubocop/cop/style/trailing_comma_in_block_args.rb, line 91
def last_comma(node)
  argument_tokens(node).last
end
trailing_comma?(node) click to toggle source
# File lib/rubocop/cop/style/trailing_comma_in_block_args.rb, line 87
def trailing_comma?(node)
  argument_tokens(node).last.comma?
end
useless_trailing_comma?(node) click to toggle source
# File lib/rubocop/cop/style/trailing_comma_in_block_args.rb, line 79
def useless_trailing_comma?(node)
  arg_count(node) > 1 && trailing_comma?(node)
end