-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed
Labels
Description
After processing the following code by using rubocop --autocorrect, NameError: undefined local variable or method 'block' occurred when running the code.
Code: (Saved as tmp05.rb and tmp05.rb.ORIG)
require 'test/unit'
class A
def initialize(aaa)
@a = aaa
end
end
module ChainFinder
def each_chain(&blk)
each_model { |model| model.each(&blk) }
end
def chains
array = []
each_model { |model| array.concat(model.chains) }
array
end
end
class TestA < Test::Unit::TestCase
def setup
@model = [A.new(1), A.new(2), A.new(3)]
end
def test_chains
expected = @model * 2
@model.instance_eval do
def chains
self
end
end
models = [@model, @model]
def models.each_model(&block)
each(&block)
end
models.extend(ChainFinder)
actual = models.chains
assert_equal(expected, actual)
end
def test_each_chain
expected = @model * 2
models = [@model, @model]
def models.each_model
each(&block)
end
models.extend(ChainFinder)
actual = []
models.each_chain { |chain| actual << chain }
assert_equal(expected, actual)
end
endExpected behavior
Corrected code runs without error and all tests passed. (Test::Unit is used in the code.)
Actual behavior
Corrected code shows NameError and a test error is shown.
See below logs for diff between the original code and auto-corrected code.
In the first-time appearance of def models.each_model, it is correctly auto-corrected to def models.each_model(&block)
But the second-time appearance, it is kept without adding (&block) block argument, but the block content is wrongly converted to use the &block argument.
Steps to reproduce the problem
$ ruby tmp05.rb
Loaded suite tmp05
Started
Finished in 0.001174086 seconds.
-----------------------------------------------------------------------------------------------------------------------------------------
2 tests, 2 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-----------------------------------------------------------------------------------------------------------------------------------------
1703.45 tests/s, 1703.45 assertions/s
$ rubocop -d -a tmp05.rb
For /XXXXX: Default configuration from /YYYYY/3.4.6/lib/ruby/gems/3.4.0/gems/rubocop-1.80.2/config/default.yml
Use parallel by default.
The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.
Please also note that you can opt-in to new cops by default by adding this to your config:
AllCops:
NewCops: enable
Gemspec/AddRuntimeDependency: # new in 1.65
Enabled: true
Gemspec/AttributeAssignment: # new in 1.77
Enabled: true
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
Enabled: true
Gemspec/DevelopmentDependencies: # new in 1.44
Enabled: true
Gemspec/RequireMFA: # new in 1.23
Enabled: true
Layout/EmptyLinesAfterModuleInclusion: # new in 1.79
Enabled: true
Layout/LineContinuationLeadingSpace: # new in 1.31
Enabled: true
Layout/LineContinuationSpacing: # new in 1.31
Enabled: true
Layout/LineEndStringConcatenationIndentation: # new in 1.18
Enabled: true
Layout/SpaceBeforeBrackets: # new in 1.7
Enabled: true
Lint/AmbiguousAssignment: # new in 1.7
Enabled: true
Lint/AmbiguousOperatorPrecedence: # new in 1.21
Enabled: true
Lint/AmbiguousRange: # new in 1.19
Enabled: true
Lint/ArrayLiteralInRegexp: # new in 1.71
Enabled: true
Lint/ConstantOverwrittenInRescue: # new in 1.31
Enabled: true
Lint/ConstantReassignment: # new in 1.70
Enabled: true
Lint/CopDirectiveSyntax: # new in 1.72
Enabled: true
Lint/DeprecatedConstants: # new in 1.8
Enabled: true
Lint/DuplicateBranch: # new in 1.3
Enabled: true
Lint/DuplicateMagicComment: # new in 1.37
Enabled: true
Lint/DuplicateMatchPattern: # new in 1.50
Enabled: true
Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
Enabled: true
Lint/DuplicateSetElement: # new in 1.67
Enabled: true
Lint/EmptyBlock: # new in 1.1
Enabled: true
Lint/EmptyClass: # new in 1.3
Enabled: true
Lint/EmptyInPattern: # new in 1.16
Enabled: true
Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
Enabled: true
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
Enabled: true
Lint/ItWithoutArgumentsInBlock: # new in 1.59
Enabled: true
Lint/LambdaWithoutLiteralBlock: # new in 1.8
Enabled: true
Lint/LiteralAssignmentInCondition: # new in 1.58
Enabled: true
Lint/MixedCaseRange: # new in 1.53
Enabled: true
Lint/NoReturnInBeginEndBlocks: # new in 1.2
Enabled: true
Lint/NonAtomicFileOperation: # new in 1.31
Enabled: true
Lint/NumberedParameterAssignment: # new in 1.9
Enabled: true
Lint/NumericOperationWithConstantResult: # new in 1.69
Enabled: true
Lint/OrAssignmentToConstant: # new in 1.9
Enabled: true
Lint/RedundantDirGlobSort: # new in 1.8
Enabled: true
Lint/RedundantRegexpQuantifiers: # new in 1.53
Enabled: true
Lint/RedundantTypeConversion: # new in 1.72
Enabled: true
Lint/RefinementImportMethods: # new in 1.27
Enabled: true
Lint/RequireRangeParentheses: # new in 1.32
Enabled: true
Lint/RequireRelativeSelfPath: # new in 1.22
Enabled: true
Lint/SharedMutableDefault: # new in 1.70
Enabled: true
Lint/SuppressedExceptionInNumberConversion: # new in 1.72
Enabled: true
Lint/SymbolConversion: # new in 1.9
Enabled: true
Lint/ToEnumArguments: # new in 1.1
Enabled: true
Lint/TripleQuotes: # new in 1.9
Enabled: true
Lint/UnescapedBracketInRegexp: # new in 1.68
Enabled: true
Lint/UnexpectedBlockArity: # new in 1.5
Enabled: true
Lint/UnmodifiedReduceAccumulator: # new in 1.1
Enabled: true
Lint/UselessConstantScoping: # new in 1.72
Enabled: true
Lint/UselessDefaultValueArgument: # new in 1.76
Enabled: true
Lint/UselessDefined: # new in 1.69
Enabled: true
Lint/UselessNumericOperation: # new in 1.66
Enabled: true
Lint/UselessOr: # new in 1.76
Enabled: true
Lint/UselessRescue: # new in 1.43
Enabled: true
Lint/UselessRuby2Keywords: # new in 1.23
Enabled: true
Metrics/CollectionLiteralLength: # new in 1.47
Enabled: true
Naming/BlockForwarding: # new in 1.24
Enabled: true
Naming/PredicateMethod: # new in 1.76
Enabled: true
Security/CompoundHash: # new in 1.28
Enabled: true
Security/IoMethods: # new in 1.22
Enabled: true
Style/AmbiguousEndlessMethodDefinition: # new in 1.68
Enabled: true
Style/ArgumentsForwarding: # new in 1.1
Enabled: true
Style/ArrayIntersect: # new in 1.40
Enabled: true
Style/BitwisePredicate: # new in 1.68
Enabled: true
Style/CollectionCompact: # new in 1.2
Enabled: true
Style/CollectionQuerying: # new in 1.77
Enabled: true
Style/CombinableDefined: # new in 1.68
Enabled: true
Style/ComparableBetween: # new in 1.74
Enabled: true
Style/ComparableClamp: # new in 1.44
Enabled: true
Style/ConcatArrayLiterals: # new in 1.41
Enabled: true
Style/DataInheritance: # new in 1.49
Enabled: true
Style/DigChain: # new in 1.69
Enabled: true
Style/DirEmpty: # new in 1.48
Enabled: true
Style/DocumentDynamicEvalDefinition: # new in 1.1
Enabled: true
Style/EmptyHeredoc: # new in 1.32
Enabled: true
Style/EmptyStringInsideInterpolation: # new in 1.76
Enabled: true
Style/EndlessMethod: # new in 1.8
Enabled: true
Style/EnvHome: # new in 1.29
Enabled: true
Style/ExactRegexpMatch: # new in 1.51
Enabled: true
Style/FetchEnvVar: # new in 1.28
Enabled: true
Style/FileEmpty: # new in 1.48
Enabled: true
Style/FileNull: # new in 1.69
Enabled: true
Style/FileRead: # new in 1.24
Enabled: true
Style/FileTouch: # new in 1.69
Enabled: true
Style/FileWrite: # new in 1.24
Enabled: true
Style/HashConversion: # new in 1.10
Enabled: true
Style/HashExcept: # new in 1.7
Enabled: true
Style/HashFetchChain: # new in 1.75
Enabled: true
Style/HashSlice: # new in 1.71
Enabled: true
Style/IfWithBooleanLiteralBranches: # new in 1.9
Enabled: true
Style/InPatternThen: # new in 1.16
Enabled: true
Style/ItAssignment: # new in 1.70
Enabled: true
Style/ItBlockParameter: # new in 1.75
Enabled: true
Style/KeywordArgumentsMerging: # new in 1.68
Enabled: true
Style/MagicCommentFormat: # new in 1.35
Enabled: true
Style/MapCompactWithConditionalBlock: # new in 1.30
Enabled: true
Style/MapIntoArray: # new in 1.63
Enabled: true
Style/MapToHash: # new in 1.24
Enabled: true
Style/MapToSet: # new in 1.42
Enabled: true
Style/MinMaxComparison: # new in 1.42
Enabled: true
Style/MultilineInPatternThen: # new in 1.16
Enabled: true
Style/NegatedIfElseCondition: # new in 1.2
Enabled: true
Style/NestedFileDirname: # new in 1.26
Enabled: true
Style/NilLambda: # new in 1.3
Enabled: true
Style/NumberedParameters: # new in 1.22
Enabled: true
Style/NumberedParametersLimit: # new in 1.22
Enabled: true
Style/ObjectThen: # new in 1.28
Enabled: true
Style/OpenStructUse: # new in 1.23
Enabled: true
Style/OperatorMethodCall: # new in 1.37
Enabled: true
Style/QuotedSymbols: # new in 1.16
Enabled: true
Style/RedundantArgument: # new in 1.4
Enabled: true
Style/RedundantArrayConstructor: # new in 1.52
Enabled: true
Style/RedundantArrayFlatten: # new in 1.76
Enabled: true
Style/RedundantConstantBase: # new in 1.40
Enabled: true
Style/RedundantCurrentDirectoryInPath: # new in 1.53
Enabled: true
Style/RedundantDoubleSplatHashBraces: # new in 1.41
Enabled: true
Style/RedundantEach: # new in 1.38
Enabled: true
Style/RedundantFilterChain: # new in 1.52
Enabled: true
Style/RedundantFormat: # new in 1.72
Enabled: true
Style/RedundantHeredocDelimiterQuotes: # new in 1.45
Enabled: true
Style/RedundantInitialize: # new in 1.27
Enabled: true
Style/RedundantInterpolationUnfreeze: # new in 1.66
Enabled: true
Style/RedundantLineContinuation: # new in 1.49
Enabled: true
Style/RedundantRegexpArgument: # new in 1.53
Enabled: true
Style/RedundantRegexpConstructor: # new in 1.52
Enabled: true
Style/RedundantSelfAssignmentBranch: # new in 1.19
Enabled: true
Style/RedundantStringEscape: # new in 1.37
Enabled: true
Style/ReturnNilInPredicateMethodDefinition: # new in 1.53
Enabled: true
Style/SafeNavigationChainLength: # new in 1.68
Enabled: true
Style/SelectByRegexp: # new in 1.22
Enabled: true
Style/SendWithLiteralMethodName: # new in 1.64
Enabled: true
Style/SingleLineDoEndBlock: # new in 1.57
Enabled: true
Style/StringChars: # new in 1.12
Enabled: true
Style/SuperArguments: # new in 1.64
Enabled: true
Style/SuperWithArgsParentheses: # new in 1.58
Enabled: true
Style/SwapValues: # new in 1.1
Enabled: true
Style/YAMLFileRead: # new in 1.53
Enabled: true
For more information: https://docs.rubocop.org/rubocop/versioning.html
Skipping parallel inspection: only a single file needs inspection
Inspecting 1 file
Scanning /XXXXX/tmp05.rb
C
Offenses:
tmp05.rb:1:1: C: [Correctable] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
require 'test/unit'
^
tmp05.rb:3:1: C: Style/Documentation: Missing top-level documentation comment for class A.
class A
^^^^^^^
tmp05.rb:9:1: C: Style/Documentation: Missing top-level documentation comment for module ChainFinder.
module ChainFinder
^^^^^^^^^^^^^^^^^^
tmp05.rb:21:1: C: Style/Documentation: Missing top-level documentation comment for class TestA.
class TestA < Test::Unit::TestCase
^^^^^^^^^^^
tmp05.rb:26:3: C: Metrics/MethodLength: Method has too many lines. [13/10]
def test_chains ...
^^^^^^^^^^^^^^^
tmp05.rb:35:7: C: [Corrected] Style/ExplicitBlockArgument: Consider using explicit block argument in the surrounding method's signature over yield.
each do |model| ...
^^^^^^^^^^^^^^^
tmp05.rb:48:7: C: [Corrected] Style/ExplicitBlockArgument: Consider using explicit block argument in the surrounding method's signature over yield.
each do |model| ...
^^^^^^^^^^^^^^^
1 file inspected, 7 offenses detected, 2 offenses corrected, 1 more offense can be corrected with `rubocop -A`
Finished in 0.38462407601764426 seconds
$ ruby tmp05.rb
Loaded suite tmp05
Started
E
=========================================================================================================================================
Error: test_each_chain(TestA): NameError: undefined local variable or method 'block' for #<Array:0x0000148d05759440>
tmp05.rb:46:in 'each_model'
tmp05.rb:11:in 'ChainFinder#each_chain'
tmp05.rb:50:in 'TestA#test_each_chain'
47: end
48: models.extend(ChainFinder)
49: actual = []
=> 50: models.each_chain { |chain| actual << chain }
51: assert_equal(expected, actual)
52: end
53: end
=========================================================================================================================================
Finished in 0.002855738 seconds.
-----------------------------------------------------------------------------------------------------------------------------------------
2 tests, 1 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications
50% passed
-----------------------------------------------------------------------------------------------------------------------------------------
700.34 tests/s, 350.17 assertions/s
$ diff -U0 tmp05.rb.ORIG tmp05.rb
--- tmp05.rb.ORIG 2025-09-18 20:16:42.333780000 +0900
+++ tmp05.rb 2025-09-18 20:17:01.041843000 +0900
@@ -34,4 +34,2 @@
- def models.each_model
- each do |model|
- yield model
- end
+ def models.each_model(&block)
+ each(&block)
@@ -48,3 +46 @@
- each do |model|
- yield model
- end
+ each(&block)
$RuboCop version
$ rubocop -V
1.80.2 (using Parser 3.3.9.0, rubocop-ast 1.46.0, analyzing as Ruby 2.7, running on ruby 3.4.6) [x86_64-linux]
$ ruby -v
ruby 3.4.6 (2025-09-16 revision dbd83256b1) +PRISM [x86_64-linux]