123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::Cop::Performance::BindCall

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, TargetRubyVersion, AutoCorrector, Base
Instance Chain:
self, RangeHelp, Base
Inherits: Base
  • Object
Defined in: lib/rubocop/cop/performance/bind_call.rb

Overview

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, …​).

Examples:

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

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

Constant Summary

Instance Method Summary

Instance Method Details

#build_call_args(call_args_node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/performance/bind_call.rb', line 71

def build_call_args(call_args_node)
  call_args_node.map(&:source).join(', ')
end

#correction_range(receiver, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/performance/bind_call.rb', line 64

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) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/performance/bind_call.rb', line 58

def message(bind_arg, call_args)
  comma = call_args.empty? ? '' : ', '

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

#on_send(node)

[ GitHub ]

  
# File 'lib/rubocop/cop/performance/bind_call.rb', line 40

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