rubocop: Naming/MemoizedInstanceVariableName false positive
$ bundle exec rubocop -V
1.9.1 (using Parser 3.0.0.0, rubocop-ast 1.4.1, running on ruby 2.7.2 x86_64-linux)
No config
Input file
# frozen_string_literal: true
module MyModule
# ...
def f
@myvar = other_method1
@myvar ||= other_method2
end
end
Expected behavior
No error. The method isn’t memoizing a value, it is recalculated every run.
Actual behavior
$ bundle exec rubocop foo.rb
Inspecting 1 file
C
Offenses:
foo.rb:3:1: C: Style/Documentation: Missing top-level module documentation comment.
module MyModule
^^^^^^
foo.rb:8:5: C: Naming/MemoizedInstanceVariableName: Memoized variable @myvar does not match method name f. Use @f instead.
@myvar ||= other_method2
^^^^^^
1 file inspected, 2 offenses detected
A workaround to avoid the false positive would be to write the code as:
def f
@myvar = other_method1 || other_method2
end
However, depending on the size and complexity of the expression, that may not be preferred. The assignment to the instance variable is the desirable side effect.
Suggestion: If final ||= expression had a previous unconditional assignment, then this offense should not occur.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 18 (13 by maintainers)
Commits related to this issue
- [Fixes #9487] Mark Naming/MemoizedInstanceVariableName as unsafe — committed to marcandre/rubocop by marcandre 3 years ago
Noting that I’m experiencing similar behavior that appears to be a false positive.
Obviously in this case, using
@before_renderwould be completely incorrect.This is not an appropriate change for the example above. In the example above, the assignment to a specific instance variable is the intended side effect. The return value is unused and ignored.
Here is a more real life scenario from a Rails controller:
In this example, changing the instance variable to
@showwould be wrong. It would be less descriptive and require changes in the show template.