class RuboCop::Cop::Style::SymbolProc

Use symbols as procs when possible.

@example

# bad
something.map { |s| s.upcase }

# good
something.map(&:upcase)

Constants

MSG
SUPER_TYPES

Public Class Methods

autocorrect_incompatible_with() click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 30
def self.autocorrect_incompatible_with
  [Layout::SpaceBeforeBlockBraces]
end

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 52
def autocorrect(node)
  lambda do |corrector|
    if node.send_node.arguments?
      autocorrect_with_args(corrector, node,
                            node.send_node.arguments,
                            node.body.method_name)
    else
      autocorrect_without_args(corrector, node)
    end
  end
end
destructuring_block_argument?(argument_node) click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 48
def destructuring_block_argument?(argument_node)
  argument_node.one? && argument_node.source.include?(',')
end
on_block(node) click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 34
def on_block(node)
  symbol_proc?(node) do |dispatch_node, arguments_node, method_name|
    # TODO: Rails-specific handling that we should probably make
    # configurable - https://github.com/rubocop-hq/rubocop/issues/1485
    # we should ignore lambdas & procs
    return if proc_node?(dispatch_node)
    return if %i[lambda proc].include?(dispatch_node.method_name)
    return if ignored_method?(dispatch_node.method_name)
    return if destructuring_block_argument?(arguments_node)

    register_offense(node, method_name, dispatch_node.method_name)
  end
end

Private Instance Methods

autocorrect_with_args(corrector, node, args, method_name) click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 83
def autocorrect_with_args(corrector, node, args, method_name)
  arg_range = args.last.source_range
  arg_range = range_with_surrounding_comma(arg_range, :right)
  replacement = " &:#{method_name}"
  replacement = ',' + replacement unless arg_range.source.end_with?(',')
  corrector.insert_after(arg_range, replacement)
  corrector.remove(block_range_with_space(node))
end
autocorrect_without_args(corrector, node) click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 78
def autocorrect_without_args(corrector, node)
  corrector.replace(block_range_with_space(node),
                    "(&:#{node.body.method_name})")
end
begin_pos_for_replacement(node) click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 98
def begin_pos_for_replacement(node)
  expr = node.send_node.source_range

  if (paren_pos = (expr.source =~ /\(\s*\)$/))
    expr.begin_pos + paren_pos
  else
    node.loc.begin.begin_pos
  end
end
block_range_with_space(node) click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 92
def block_range_with_space(node)
  block_range = range_between(begin_pos_for_replacement(node),
                              node.loc.end.end_pos)
  range_with_surrounding_space(range: block_range, side: :left)
end
register_offense(node, method_name, block_method_name) click to toggle source
# File lib/rubocop/cop/style/symbol_proc.rb, line 66
def register_offense(node, method_name, block_method_name)
  block_start = node.loc.begin.begin_pos
  block_end = node.loc.end.end_pos
  range = range_between(block_start, block_end)

  add_offense(node,
              location: range,
              message: format(MSG,
                              method: method_name,
                              block_method: block_method_name))
end