class RuboCop::Cop::Performance::BindCall
umethod.bind_call(obj, foo, bar)
# good
umethod.bind(obj).(foo, bar)
umethod.bind(obj).call(foo, bar)
# bad
@example
`bind(obj).call(args, …)‘.
The `bind_call(obj, args, …)` method is faster than
can be replaced by `bind_call(obj, args, …)`.
This cop identifies places where `bind(obj).call(args, …)`
In Ruby 2.7, `UnboundMethod#bind_call` has been added.
def build_call_args(call_args_node)
def build_call_args(call_args_node) call_args_node.map(&:source).join(', ') end
def correction_range(receiver, node)
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
def message(bind_arg, call_args)
def message(bind_arg, call_args) comma = call_args.empty? ? '' : ', ' format(MSG, bind_arg: bind_arg, comma: comma, call_args: call_args) end
def on_send(node)
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