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
foo
I 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
foo
If 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.rb and .rubocop.yml files into that directory.
Run ruby foo.rb, and observe that it runs without failing.
When code violates both
Naming/BlockForwarding
andPerformance/BlockGivenWithExplicitBlock
, performing a safe autocorrect on that code can result in incorrect code.Expected behavior
When running
rubocop -a foo.rb
wherefoo.rb
is the following file:And where your
.rubocop.yml
is as follows:I expect either the
Naming/BlockForwarding
or thePerformance/BlockGivenWithExplicitBlock
safe autocorrect to be applied, but not both.Actual behavior
It safe autocorrects to:
If you try running this code using
ruby foo.rb
, it will fail. ThePerformance/BlockGivenWithExplicitBlock
cop safe autocorrect was applied, soblock_given?
is changed to justblock
. TheNaming/BlockForwarding
cop safe autocorrect was applied, so usage of&block
is changed to just&
. This means that where we are referencingblock
, we are referencing an undefined variable. When you run the code you encounter the following error:Steps to reproduce the problem
foo.rb
and.rubocop.yml
files into that directory.ruby foo.rb
, and observe that it runs without failing.rubocop -a foo.rb
.ruby foo.rb
, and observe that it fails.RuboCop version