rubocop / rubocop-performance

An extension of RuboCop focused on code performance checks.
https://docs.rubocop.org/rubocop-performance
MIT License
686 stars 81 forks source link

False positive for Performance/BindCall #464

Closed TastyPi closed 2 months ago

TastyPi commented 2 months ago
def example(&block)
  block.bind(self).call { puts "inner block" }
end

gets turned into

def example(&block)
  block.bind_call(self) { puts "inner block" }
end

but block doesn't have a bind_call method because it isn't a method, so this throws NoMethodError: undefined methodbind_call' for an instance of Proc`


Expected behavior

Should ignore bind methods called on block parameters.

Actual behavior

Generates invalid code (see above)

Steps to reproduce the problem

See example above

RuboCop version

1.65.1 (using Parser 3.3.5.0, rubocop-ast 1.32.3, running on ruby 3.3.4) +server [x86_64-linux]
  - rubocop-capybara 2.21.0
  - rubocop-i18n 1.14.5
  - rubocop-minitest 0.36.0
  - rubocop-performance 1.21.1
  - rubocop-rails 2.25.1
  - rubocop-rake 0.6.0
  - rubocop-thread_safety 0.5.1
Earlopain commented 2 months ago

Proc also doesn't respond to bind so isn't the code broken to begin with? This results in NoMethodError before and after correction.

TastyPi commented 2 months ago

Oh, I did not realise I was getting this functionality from a gem, nevermind https://github.com/thoughtbot/shoulda-context/blob/main/lib/shoulda/context/proc_extensions.rb

Earlopain commented 2 months ago

Thanks for the context, that's a blast from the past. Apparently rails removed that in 4.1. Also see https://github.com/rails/rails/pull/5552. Maybe you can also just use instance_exec https://github.com/thoughtbot/shoulda-context/commit/e80456bb9cf3bd5e16af67b6fd077004adf6e1a2? Just a sidenote, the GC caveat doesn't apply anymore today, symbols are garbage collected.