-
-
Notifications
You must be signed in to change notification settings - Fork 88
Description
When code violates both Naming/BlockForwarding and Performance/BlockGivenWithExplicitBlock, performing a safe autocorrect on that code can result in incorrect code.
Expected behavior
When running rubocop -a foo.rb where foo.rb is the following file:
# frozen_string_literal: true
def bar
puts 'bar!'
yield
end
def foo(&block)
if block_given?
bar(&block)
else
puts 'no block'
end
end
foo do
puts 'the block'
end
fooAnd where your .rubocop.yml is as follows:
require:
- rubocop-performance
AllCops:
NewCops: enable
TargetRubyVersion: 3.2I expect either the Naming/BlockForwarding or the Performance/BlockGivenWithExplicitBlock safe autocorrect to be applied, but not both.
Actual behavior
It safe autocorrects to:
# frozen_string_literal: true
def bar
puts 'bar!'
yield
end
def foo(&)
if block
bar(&)
else
puts 'no block'
end
end
foo do
puts 'the block'
end
fooIf you try running this code using ruby foo.rb, it will fail. The Performance/BlockGivenWithExplicitBlock cop safe autocorrect was applied, so block_given? is changed to just block. The Naming/BlockForwarding cop safe autocorrect was applied, so usage of &block is changed to just &. This means that where we are referencing block, we are referencing an undefined variable. When you run the code you encounter the following error:
foo.rb:9:in `foo': undefined local variable or method `block' for main:Object (NameError)
if block
^^^^^
from foo.rb:16:in `<main>'
Steps to reproduce the problem
- Set your Ruby version to 3.2.
- Create an empty directory.
- Put the above
foo.rband.rubocop.ymlfiles into that directory. - Run
ruby foo.rb, and observe that it runs without failing. - Run
rubocop -a foo.rb. - Run
ruby foo.rb, and observe that it fails.
RuboCop version
> rubocop -V
1.60.2 (using Parser 3.3.0.5, rubocop-ast 1.30.0, running on ruby 3.2.2) [arm64-darwin22]
- rubocop-performance 1.20.2