New features
- #15166: Add a new
Recursiveoption toStyle/MutableConstant. When enabled, the cop checks and freezes mutable literals nested inside arrays and hashes. The option is disabled by default to preserve existing behavior. (@paracycle)
Bug fixes
- #15220: Fix a bad autocorrect for
Lint/RedundantSplatExpansionwhen splatting an empty literal (e.g.when *[]orrescue *[]), which expanded to invalid or semantically different code. (@bbatsov) - #15221: Fix a bad autocorrect for
Lint/RegexpAsConditionwhen the regexp literal is negated (e.g.if !/foo/), which inverted the condition. (@bbatsov) - #15242: Fix a bad autocorrect for
Lint/SymbolConversionwhen the receiver is an interpolated string containing an embedded double quote (e.g."foo#{bar}\"qux".to_sym), which produced a syntax error. (@bbatsov) - #15270: Fix a crash for
Style/CombinableLoopswhen aforloop has an empty body, and stop autocorrecting consecutiveforloops whose iteration variables differ (which produced code referencing an undefined variable). (@bbatsov) - #15272: Fix a crash for
Style/ConstantVisibilitywhen a visibility declaration has a numeric literal argument (e.g.private_constant 42). (@bbatsov) - #15215: Fix a false negative for
Lint/OrderedMagicCommentswhen anencodingmagic comment is preceded by a magic comment other thanfrozen_string_literal(e.g.shareable_constant_value). (@bbatsov) - #15228: Fix a false negative for
Lint/RedundantWithIndexwhen the block takes no arguments (e.g.ary.each_with_index { do_something }). (@bbatsov) - #15230: Fix a false negative for
Lint/RequireRelativeSelfPathwhen requiring the current file by name with its extension (e.g.require_relative 'foo.rb') and the file path is absolute. (@bbatsov) - #15229: Fix a false negative for
Lint/SafeNavigationChainwhen an ordinary method is chained after a parenthesized safe navigation call (e.g.(x&.foo).bar). (@bbatsov) - #15225: Fix a false negative for
Lint/SafeNavigationWithEmptywhen the receiver of&.empty?is a local variable, instance variable, constant, or other non-method-call expression. (@bbatsov) - #15231: Fix a false negative for
Lint/SendWithMixinArgumentwhensend/public_send/__send__is called with no explicit receiver or with aselfreceiver (e.g.send(:include, Bar)). (@bbatsov) - #15248: Fix a false negative for
Lint/ToEnumArgumentswhen more positional arguments are passed than the method accepts (e.g.def m(x); to_enum(:m, x, extra); end), which raisesArgumentErrorwhen the enumerator is used. (@bbatsov) - #15249: Fix a false negative for
Lint/UnescapedBracketInRegexpwhen an unescaped]is preceded by an escaped backslash (e.g./abc\\]123/). (@bbatsov) - #15267: Fix a false positive for
Style/ArrayIntersectWithSingleElementwith a splat argument (e.g.array.intersect?([*foo])), which is not a single element and was incorrectly rewritten toarray.include?(*foo). (@bbatsov) - #15272: Fix a false positive for
Style/ColonMethodCallwith chained JRuby interop calls (e.g.Java::com::something_method). (@bbatsov) - #15271: Fix a false positive for
Style/ConditionalAssignmentwithEnforcedStyle: assign_inside_conditionwhen assigning anunlesswithout anelsebranch (e.g.x = unless cond; 1; end), which was rewritten to move the assignment inside theunlessand changed behavior when the condition was true. (@bbatsov) - #14401: Fix a false positive for
Layout/BlockAlignmentwithEnforcedStyleAlignWith: start_of_linewhen a block is passed as a method argument. (@augustocbx) - #15216: Fix a false positive for
Lint/RaiseExceptionwhenraise Exceptionis used inside a module nested within an allowed implicit namespace (e.g.Gem). (@bbatsov) - #15219: Fix a false positive for
Lint/RedundantDirGlobSortwhensortis given a comparator block or a block-pass argument, which is not redundant with the default sorting. (@bbatsov) - #15224: Fix a false positive for
Lint/ShadowingOuterLocalVariablewhen a block argument has the same name as a pattern variable from a differentinbranch of the samecase. (@bbatsov) - #15239: Fix a false positive for
Lint/SuppressedExceptionInNumberConversionwhen the numeric constructor already passesexception: false(e.g.Integer(arg, exception: false) rescue nil), which also produced an autocorrect with a duplicateexception: falsekeyword. (@bbatsov) - #15243: Fix a false positive for
Lint/TopLevelReturnWithArgumentwhen areturnwith an argument is inside a numbered-parameter block or anitblock. (@bbatsov) - #15245: Fix a false positive for
Lint/UselessRuby2Keywordswhenruby2_keywordsin a nested class or module refers to a method of the same name defined in an outer scope. (@bbatsov) - #15246: Fix a false positive for
Lint/UselessSetterCallwhen a multiple assignment uses nested destructuring (e.g.(a, b), c = arg, other_arg), which misaligned variables with the right-hand side values. (@bbatsov) - #15125: Fix a false positive for
Style/ZeroLengthPredicatewhenFile::Stat.new(...).size.zero?is used. (@augustocbx) - #15196: Fix
--start-serverto wait until the server is running before returning, which fixes a flaky--restart-serverspec and a race for commands run right after starting the server. (@koic) - #15272: Fix
Style/Aliasnot detecting block scope for numbered-parameter anditblocks, which caused a false positive foralias_methodand a false negative foraliasinside such blocks. (@bbatsov) - #15281: Fix an incorrect autocorrect when
Style/IfUnlessModifierandStyle/Nextcorrect the same conditional. (@fynsta) - #15260: Fix an error for
Style/FileWritewhen a literal or variable is passed towritein the block form. (@koic) - #15276: Fix an error for
Style/RedundantFormatwhen the format string is a heredoc with format arguments. (@fynsta) - #15270: Fix an incorrect autocorrect for
Style/AndOrwhen an operand isnext,break, oryieldwith an argument (e.g.foo and next 1), which produced invalid Ruby likefoo && next 1. (@bbatsov) - #15267: Fix an incorrect autocorrect for
Style/ArrayFirstLastwhenarr[0]/arr[-1]is the target of a compound assignment (e.g.arr[0] += 1), which producedarr.first += 1and raisedNoMethodError. (@bbatsov) - #15267: Fix an incorrect autocorrect for
Style/ArrayIntersectwhere a negated predicate on a safe-navigation chain (e.g.a&.intersection(b)&.none?) was rewritten to!a&.intersect?(b), flipping the result when the receiver isnil. (@bbatsov) - #15273: Fix an incorrect autocorrect for
Style/BlockDelimitersthat converted a single-linedo...endblock containing a block-levelrescueorensureto{...}, producing invalid Ruby. (@bbatsov) - #15268: Fix an incorrect autocorrect for
Style/CaseEqualitywhen the argument is an operator or unary expression (e.g.Array === a + b), which produced mis-parsed code likea + b.is_a?(Array). (@bbatsov) - #15268: Fix an incorrect autocorrect for
Style/ClassEqualityComparisoninside a namespace when the class name string is already fully qualified (e.g.bar.class.name == '::Bar'), which producedinstance_of?(::::Bar)and was a syntax error. (@bbatsov) - #15268: Fix an incorrect autocorrect for
Style/ClassEqualityComparisonwhen comparingClassitself to a string literal (e.g.var.class == 'Date'), which producedvar.instance_of?('Date')and raisedTypeError; such comparisons are no longer autocorrected. (@bbatsov) - #15274: Fix an incorrect autocorrect for
Style/ClassMethodsDefinitionsthat corrupted a preceding comment containingdef <name>and left the method undefined as a class method. (@bbatsov) - #15270: Fix an incorrect autocorrect for
Style/ComparableClampwhen the clamped value is an operator expression (e.g.a + b), which produced mis-parsed code likea + b.clamp(low, high). (@bbatsov) - #15267: Fix an incorrect autocorrect for
Style/ConcatArrayLiteralswith an empty array literal argument (e.g.arr.concat([], [b])), which produced invalid Ruby likearr.push(, b). (@bbatsov) - #15274: Fix an incorrect autocorrect for
Style/DigChainthat duplicated a trailing comment and dropped indentation when the chain was inside a method or block. (@bbatsov) - #15288: Fix an incorrect autocorrect for
Lint/UselessTimeswhen a1.timesblock takes a single destructured (|(a, b)|) or splat (|*a|) argument, which produced a body referencing an undefined variable. (@bbatsov) - #15280: Fix an incorrect autocorrect for
Style/ConditionalAssignmentwithEnforcedStyle: assign_inside_conditionand a single-linecase. (@fynsta) - #15278: Fix an incorrect autocorrect for
Style/ParallelAssignmentwhen the right-hand side contains a heredoc. (@fynsta) - #15279: Fix an incorrect autocorrect for
Style/Semicolonwhen a heredoc is opened before the semicolon. (@fynsta) - #15277: Fix an incorrect autocorrect for
Style/WordArraywhen the array contains heredocs. (@fynsta) - #15240: Fix an incorrect autocorrect for
Lint/UselessAssignmentthat rewrote a first-seenfoo &&= 1tofoo && 1, raisingNameErrorat runtime. (@bbatsov) - #15269: Fix a false positive where a cop's relative
Includepattern could match directories above the project root. (@augustocbx) - #15209: Fix a false negative for
Lint/InterpolationCheckwhen interpolation appears in a multiline single-quoted string. (@bbatsov) - #15211: Fix a false negative for
Lint/NonLocalExitFromIteratorwhen the iterator receiver uses safe navigation. (@bbatsov) - #15227: Fix false negatives for
Lint/RedundantSafeNavigationwith&.respond_to?on a guaranteed-instance receiver (e.g.foo.to_s&.respond_to?(:class)) and with&.to_husing a numbered-parameter oritblock (e.g.foo&.to_h { _1 } || {}). (@bbatsov) - #15226: Fix false negatives for
Lint/RescueTypewhen rescuing fromtrue,false, a rational literal (1r), or a complex literal (1i), all of which raise aTypeErrorat runtime. (@bbatsov) - #15233: Fix false negatives for
Lint/SelfAssignmentwith||=and&&=on constants, attributes, and hash keys (e.g.Foo ||= Foo,foo.bar ||= foo.bar,hash['foo'] ||= hash['foo']). (@bbatsov) - #15247: Fix false negatives for
Lint/SharedMutableDefaultwhen a mutable default is combined with acapacity:keyword argument and given as an array orArray.new/Hash.new(e.g.Hash.new([], capacity: 42)). (@bbatsov) - #15206: Fix a false positive for
Lint/FloatComparisonwhen comparing against a parenthesized zero ornil. (@bbatsov) - #15208: Fix a false positive for
Lint/IncompatibleIoSelectWithFiberSchedulerwhen the single array argument element is a splat. (@bbatsov) - #15207: Fix a false positive for
Lint/LiteralAssignmentInConditionwhen a literal is assigned inside a block in the condition. (@bbatsov) - #15272: Fix false positives for
Style/DateTime: a bareto_datetimecall on implicit self is no longer flagged, and historic-date calls using safe navigation (e.g.DateTime&.iso8601(str, Date::ENGLAND)) are now exempted. (@bbatsov) - #14979: Fix false positives in
Layout/BlockAlignmentwhen there is a line break between method arguments before the block. (@koic) - #15204: Fix false positives in
Lint/EnsureReturnandLint/NoReturnInBeginEndBlocksforreturninside a nested method definition or lambda. (@bbatsov) - #15197: Fix false positives in
Style/WhileUntilDowhen the loop body is on the same line as thedokeyword. (@koic) - #15205: Fix an incorrect autocorrect for
Lint/ErbNewArgumentswhen a keyword argument follows thesafe_levelargument. (@bbatsov) - #15210: Fix an incorrect autocorrect for
Lint/LambdaWithoutLiteralBlockthat dropped safe navigation from the block argument. (@bbatsov) - #15214: Fix an incorrect autocorrect for
Lint/NumericOperationWithConstantResultwhen using safe navigation, as the result isnilwhen the receiver isnil. (@bbatsov) - #15217: Fix an incorrect autocorrect for
Lint/RedundantCopDisableDirectiveandLint/RedundantCopEnableDirectivewhen a cop name in the directive is a prefix of another cop name in the same directive (e.g.Lint/AmbiguousOperatorandLint/AmbiguousOperatorPrecedence). (@bbatsov) - #15275: Fix incorrect autocorrects for
Style/FileWritethat deleted or duplicated heredoc bodies when a heredoc was used as the filename, in an argument expression, or in an inline block. (@fynsta) - #15241: Fix incorrect autocorrects for
Lint/UselessTimeswhen thetimesblock usesnext/break(which became a syntax error) or takes multiple block arguments (which became undefined references). (@bbatsov) - #15222: Fix
Lint/ScriptPermissionto honor a cop-levelAutoCorrect: falsesetting and to not crash on sources without a file on disk (e.g. unsaved editor buffers). (@bbatsov) - #15244: Fix
Lint/TrailingCommaInAttributeDeclarationto detect a trailing comma before a singleton method definition (e.g.def self.bar) and to not crash when adefis the sole argument (e.g.attr_reader def bar; end). (@bbatsov) - #15250: Fix incorrect autocorrects for
Lint/LiteralInInterpolationwith embedded quotes and escaped interpolation text. (@RedZapdos123) - #15291: Fix an incorrect autocorrect for
Lint/LiteralInInterpolationwhen interpolated hashes contain symbols that require quoted syntax, such as:'foo-bar'. (@RedZapdos123) - #14364: Fix
.rubocop_todo.ymlautocorrect safety comments for local custom cops configured in the project config. (@RedZapdos123) - #15252: Stop autocorrecting
Lint/NumberConversionoffenses on safe navigation calls. (@RedZapdos123) - #12276: Fix
--auto-gen-configto record--disable-pending-copsand--enable-pending-copsin the generated.rubocop_todo.ymlcommand so that--regenerate-todopreserves them. (@augustocbx) - #15202: Fix
InternalAffairs/RedundantLetRuboCopConfigNewcrash whenlet(:config)has no enclosingdescribe. (@bbatsov)
Changes
- #15234: Reword the
Lint/RequireRangeParenthesesoffense message, which incorrectly called the flagged (finite) range "endless". (@bbatsov) - #15235: Add autocorrection to
Lint/RefinementImportMethods(replacinginclude/prependwithimport_methods) and report that the functionality was removed (not just deprecated) on Ruby 3.2+. (@bbatsov) - #15198: Reword cop descriptions that did not start with a verb (e.g.
Lint/UnreachableCode,Metrics/AbcSize,Security/Eval) for consistency. (@bbatsov) - #15223: Make
Lint/RedundantWithObjectautocorrect unsafe, sinceeach_with_objectreturns the memo object while the correctedeachreturns the receiver. (@bbatsov) - #15194: Rename inconsistently named cop parameters to follow RuboCop's conventions (the old names are deprecated but still work):
Bundler/GemComment'sIgnoredGemstoAllowedGems,Lint/NumberConversion'sIgnoredClassestoAllowedClasses,Lint/MissingCopEnableDirective'sMaximumRangeSizetoMaxRangeSize,Metrics/CollectionLiteralLength'sLengthThresholdtoMax, andStyle/FetchEnvVar'sAllowedVarstoAllowedVariables. (@bbatsov)