-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
(thanks for working on Rubocop! 🙏 apologies if this has already been addressed.)
When a local variable is set using conditional assignment with the result from another module method, and safe-autocorrect with Style/RedundantSelf
is run, then self
is removed but the behaviour of the code changes completely.
I think it makes sense for the cop warning to be raised, but the safe auto-correct shouldn't break the code or change its behaviour. An unsafe autocorrect would be fine, of course.
I understand that conditional assignment would be pointless in the example below, but sometimes you have a lot of these issues to comb through. Having the safe-autocorrect changing the behaviour of the code wasn't expected.
Happy to try and put in a fix for this in case it's really a bug.
Expected behavior
Running bundle exec rubocop --only Style/RedundantSelf rubocop_redundant_self.rb -a
should not change the behaviour of the code below.
module RubocopRedundantSelf
def self.example
foo ||= self.foo
end
def self.foo
"hello"
end
end
Actual behavior
The behaviour of the code changes - now foo
is always nil:
module RubocopRedundantSelf
def self.example
foo ||= foo # <-- self is removed here
end
# (...)
end
Steps to reproduce the problem
Full sample code:
module RubocopRedundantSelf
def self.example
foo ||= self.foo
if foo.nil?
raise "foo must not be nil"
end
foo
end
def self.foo
"hello"
end
end
puts RubocopRedundantSelf.example
- if you run the code, it works fine:
$ ruby rubocop_redundant_self.rb
#=> hello
- Run safe autocorrect:
$ rubocop --only Style/RedundantSelf -a
C: [Corrected] Style/RedundantSelf: Redundant self detected.
foo ||= self.foo
^^^^
1 file inspected, 2 offenses detected, 1 offense corrected
- Resulting code:
module RubocopRedundantSelf
def self.example
foo ||= foo # <---- self is removed here
if foo.nil?
raise "foo must not be nil"
end
foo
end
def self.foo
"hello"
end
end
puts RubocopRedundantSelf.example
- If you run the code, the behaviour changes:
rubocop_redundant_self.rb:6:in 'RubocopRedundantSelf.example': foo must not be nil (RuntimeError)
from rubocop_redundant_self.rb:17:in '<main>'
RuboCop version
1.76.2 (using Parser 3.3.8.0, Prism 1.4.0, rubocop-ast 1.45.1, analyzing as Ruby 3.4, running on ruby 3.4.4) [arm64-darwin24]
Full debug output:
bundle exec rubocop --debug --only Style/RedundantSelf rubocop_redundant_self.rb -a --debug
For (...): configuration from .rubocop.yml
Inheriting configuration from .rubocop.project.yml
Default configuration from .bundle/ruby/3.4.0/gems/rubocop-1.76.2/config/default.yml
Use parallel by default.
Skipping parallel inspection: only a single file needs inspection
Inspecting 1 file
Scanning rubocop_redundant_self.rb
C
Offenses:
rubocop_redundant_self.rb:3:13: C: [Corrected] Style/RedundantSelf: Redundant self detected.
foo ||= self.foo
^^^^