class RuboCop::Cop::Performance::BindCall

In Ruby 2.7, `UnboundMethod#bind_call` has been added.

This cop identifies places where `bind(obj).call(args, …)` can be replaced by `bind_call(obj, args, …)`.

The `bind_call(obj, args, …)` method is faster than `bind(obj).call(args, …)`.

@example

# bad
umethod.bind(obj).call(foo, bar)
umethod.bind(obj).(foo, bar)

# good
umethod.bind_call(obj, foo, bar)

Constants

MSG
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/performance/bind_call.rb, line 41
def on_send(node)
  return unless (receiver, bind_arg, call_args_node = bind_with_call_method?(node))

  range = correction_range(receiver, node)
  call_args = build_call_args(call_args_node)
  message = message(bind_arg.source, call_args)

  add_offense(range, message: message) do |corrector|
    call_args = ", #{call_args}" unless call_args.empty?

    replacement_method = "bind_call(#{bind_arg.source}#{call_args})"

    corrector.replace(range, replacement_method)
  end
end

Private Instance Methods

build_call_args(call_args_node) click to toggle source
# File lib/rubocop/cop/performance/bind_call.rb, line 72
def build_call_args(call_args_node)
  call_args_node.map(&:source).join(', ')
end
correction_range(receiver, node) click to toggle source
# File lib/rubocop/cop/performance/bind_call.rb, line 65
def correction_range(receiver, node)
  location_of_bind = receiver.loc.selector.begin_pos
  location_of_call = node.source_range.end.end_pos

  range_between(location_of_bind, location_of_call)
end
message(bind_arg, call_args) click to toggle source
# File lib/rubocop/cop/performance/bind_call.rb, line 59
def message(bind_arg, call_args)
  comma = call_args.empty? ? '' : ', '

  format(MSG, bind_arg: bind_arg, comma: comma, call_args: call_args)
end