Style

Style/AccessModifierDeclarations

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.57

0.81

Access modifiers should be declared to apply to a group of methods or inline before each method, depending on configuration. EnforcedStyle config covers only method definitions. Applications of visibility methods to symbols can be controlled using AllowModifiersOnSymbols config. Also, the visibility of attr* methods can be controlled using AllowModifiersOnAttrs config.

In Ruby 3.0, attr* methods now return an array of defined method names as symbols. So we can write the modifier and attr* in inline style. AllowModifiersOnAttrs config allows attr* methods to be written in inline style without modifying applications that have been maintained for a long time in group style. Furthermore, developers who are not very familiar with Ruby may know that the modifier applies to def, but they may not know that it also applies to attr* methods. It would be easier to understand if we could write attr* methods in inline style.

Safety

Autocorrection is not safe, because the visibility of dynamically defined methods can vary depending on the state determined by the group access modifier.

Examples

EnforcedStyle: group (default)

# bad
class Foo

  private def bar; end
  private def baz; end

end

# good
class Foo

  private

  def bar; end
  def baz; end

end

EnforcedStyle: inline

# bad
class Foo

  private

  def bar; end
  def baz; end

end

# good
class Foo

  private def bar; end
  private def baz; end

end

AllowModifiersOnSymbols: true (default)

# good
class Foo

  private :bar, :baz
  private *%i[qux quux]
  private *METHOD_NAMES

end

AllowModifiersOnSymbols: false

# bad
class Foo

  private :bar, :baz
  private *%i[qux quux]
  private *METHOD_NAMES

end

AllowModifiersOnAttrs: true (default)

# good
class Foo

  public attr_reader :bar
  protected attr_writer :baz
  private attr_accessor :qux
  private attr :quux

  def public_method; end

  private

  def private_method; end

end

AllowModifiersOnAttrs: false

# bad
class Foo

  public attr_reader :bar
  protected attr_writer :baz
  private attr_accessor :qux
  private attr :quux

end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

group

inline, group

AllowModifiersOnSymbols

true

Boolean

AllowModifiersOnAttrs

true

Boolean

Style/AccessorGrouping

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.87

-

Checks for grouping of accessors in class and module bodies. By default it enforces accessors to be placed in grouped declarations, but it can be configured to enforce separating them in multiple declarations.

If there is a method call before the accessor method it is always allowed as it might be intended like Sorbet.
If there is a RBS::Inline annotation comment just after the accessor method it is always allowed.

Examples

EnforcedStyle: grouped (default)

# bad
class Foo
  attr_reader :bar
  attr_reader :bax
  attr_reader :baz
end

# good
class Foo
  attr_reader :bar, :bax, :baz
end

# good
class Foo
  # may be intended comment for bar.
  attr_reader :bar

  sig { returns(String) }
  attr_reader :bax

  may_be_intended_annotation :baz
  attr_reader :baz
end

EnforcedStyle: separated

# bad
class Foo
  attr_reader :bar, :baz
end

# good
class Foo
  attr_reader :bar
  attr_reader :baz
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

grouped

separated, grouped

Style/Alias

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.36

Enforces the use of either #alias or #alias_method depending on configuration. It also flags uses of alias :symbol rather than alias bareword.

However, it will always enforce method_alias when used alias in an instance method definition and in a singleton method definition. If used in a block, always enforce alias_method unless it is an instance_eval block.

Examples

EnforcedStyle: prefer_alias (default)

# bad
alias_method :bar, :foo
alias :bar :foo

# good
alias bar foo

EnforcedStyle: prefer_alias_method

# bad
alias :bar :foo
alias bar foo

# good
alias_method :bar, :foo

Configurable attributes

Name Default value Configurable values

EnforcedStyle

prefer_alias

prefer_alias, prefer_alias_method

Style/AmbiguousEndlessMethodDefinition

Required Ruby version: 3.0
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.68

-

Looks for endless methods inside operations of lower precedence (and, or, and modifier forms of if, unless, while, until) that are ambiguous due to lack of parentheses. This may lead to unexpected behavior as the code may appear to use these keywords as part of the method but in fact they modify the method definition itself.

In these cases, using a normal method definition is more clear.

Examples

# bad
def foo = true if bar

# good - using a non-endless method is more explicit
def foo
  true
end if bar

# ok - method body is explicit
def foo = (true if bar)

# ok - method definition is explicit
(def foo = true) if bar

Style/AndOr

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.9

1.21

Checks for uses of and and or, and suggests using && and || instead. It can be configured to check only in conditions or in all contexts.

Safety

Autocorrection is unsafe because there is a different operator precedence between logical operators (&& and ||) and semantic operators (and and or), and that might change the behavior.

Examples

EnforcedStyle: conditionals (default)

# bad
if foo and bar
end

# good
foo.save && return

# good
foo.save and return

# good
if foo && bar
end

EnforcedStyle: always

# bad
foo.save and return

# bad
if foo and bar
end

# good
foo.save && return

# good
if foo && bar
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

conditionals

always, conditionals

Style/ArgumentsForwarding

Required Ruby version: 2.7
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.1

1.58

In Ruby 2.7, arguments forwarding has been added.

This cop identifies places where do_something(*args, &block) can be replaced by do_something(…​).

In Ruby 3.1, anonymous block forwarding has been added.

This cop identifies places where do_something(&block) can be replaced by do_something(&); if desired, this functionality can be disabled by setting UseAnonymousForwarding: false.

In Ruby 3.2, anonymous args/kwargs forwarding has been added.

This cop also identifies places where use_args(args)/use_kwargs(kwargs) can be replaced by use_args()/use_kwargs(); if desired, this functionality can be disabled by setting UseAnonymousForwarding: false.

And this cop has RedundantRestArgumentNames, RedundantKeywordRestArgumentNames, and RedundantBlockArgumentNames options. This configuration is a list of redundant names that are sufficient for anonymizing meaningless naming.

Meaningless names that are commonly used can be anonymized by default: e.g., args, *options, &block, and so on.

Names not on this list are likely to be meaningful and are allowed by default.

This cop handles not only method forwarding but also forwarding to super.

Examples

# bad
def foo(*args, &block)
  bar(*args, &block)
end

# bad
def foo(*args, **kwargs, &block)
  bar(*args, **kwargs, &block)
end

# good
def foo(...)
  bar(...)
end

UseAnonymousForwarding: true (default, only relevant for Ruby >= 3.2)

# bad
def foo(*args, **kwargs, &block)
  args_only(*args)
  kwargs_only(**kwargs)
  block_only(&block)
end

# good
def foo(*, **, &)
  args_only(*)
  kwargs_only(**)
  block_only(&)
end

UseAnonymousForwarding: false (only relevant for Ruby >= 3.2)

# good
def foo(*args, **kwargs, &block)
  args_only(*args)
  kwargs_only(**kwargs)
  block_only(&block)
end

AllowOnlyRestArgument: true (default, only relevant for Ruby < 3.2)

# good
def foo(*args)
  bar(*args)
end

def foo(**kwargs)
  bar(**kwargs)
end

AllowOnlyRestArgument: false (only relevant for Ruby < 3.2)

# bad
# The following code can replace the arguments with `...`,
# but it will change the behavior. Because `...` forwards block also.
def foo(*args)
  bar(*args)
end

def foo(**kwargs)
  bar(**kwargs)
end

RedundantRestArgumentNames: ['args', 'arguments'] (default)

# bad
def foo(*args)
  bar(*args)
end

# good
def foo(*)
  bar(*)
end

RedundantKeywordRestArgumentNames: ['kwargs', 'options', 'opts'] (default)

# bad
def foo(**kwargs)
  bar(**kwargs)
end

# good
def foo(**)
  bar(**)
end

RedundantBlockArgumentNames: ['blk', 'block', 'proc'] (default)

# bad - But it is good with `EnforcedStyle: explicit` set for `Naming/BlockForwarding`.
def foo(&block)
  bar(&block)
end

# good
def foo(&)
  bar(&)
end

Configurable attributes

Name Default value Configurable values

AllowOnlyRestArgument

true

Boolean

UseAnonymousForwarding

true

Boolean

RedundantRestArgumentNames

args, arguments

Array

RedundantKeywordRestArgumentNames

kwargs, options, opts

Array

RedundantBlockArgumentNames

blk, block, proc

Array

Style/ArrayCoercion

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

No

Always (Unsafe)

0.88

-

Enforces the use of Array() instead of explicit Array check or [*var].

The cop is disabled by default due to safety concerns.

Safety

This cop is unsafe because a false positive may occur if the argument of Array() is (or could be) nil or depending on how the argument is handled by Array() (which can be different than just wrapping the argument in an array).

For example:

[nil]             #=> [nil]
Array(nil)        #=> []

[{a: 'b'}]        #= [{a: 'b'}]
Array({a: 'b'})   #=> [[:a, 'b']]

[Time.now]        #=> [#<Time ...>]
Array(Time.now)   #=> [14, 16, 14, 16, 9, 2021, 4, 259, true, "EDT"]

Examples

# bad
paths = [paths] unless paths.is_a?(Array)
paths.each { |path| do_something(path) }

# bad (always creates a new Array instance)
[*paths].each { |path| do_something(path) }

# good (and a bit more readable)
Array(paths).each { |path| do_something(path) }

Style/ArrayFirstLast

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

No

Always (Unsafe)

1.58

-

Identifies usages of arr[0] and arr[-1] and suggests to change them to use arr.first and arr.last instead.

The cop is disabled by default due to safety concerns.

Safety

This cop is unsafe because [0] or [-1] can be called on a Hash, which returns a value for 0 or -1 key, but changing these to use .first or .last will return first/last tuple instead. Also, String does not implement first/last methods.

Examples

# bad
arr[0]
arr[-1]

# good
arr.first
arr.last
arr[0] = 2
arr[0][-2]

References

  • #first-and-last

Style/ArrayIntersect

Required Ruby version: 3.1
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.40

-

In Ruby 3.1, Array#intersect? has been added.

This cop identifies places where (array1 & array2).any? can be replaced by array1.intersect?(array2).

The array1.intersect?(array2) method is faster than (array1 & array2).any? and is more readable.

In cases like the following, compatibility is not ensured, so it will not be detected when using block argument.

([1] & [1,2]).any? { |x| false }    # => false
[1].intersect?([1,2]) { |x| false } # => true

Safety

This cop cannot guarantee that array1 and array2 are actually arrays while method intersect? is for arrays only.

Examples

# bad
(array1 & array2).any?
(array1 & array2).empty?

# good
array1.intersect?(array2)
!array1.intersect?(array2)

AllCops:ActiveSupportExtensionsEnabled: false (default)

# good
(array1 & array2).present?
(array1 & array2).blank?

AllCops:ActiveSupportExtensionsEnabled: true

# bad
(array1 & array2).present?
(array1 & array2).blank?

# good
array1.intersect?(array2)
!array1.intersect?(array2)

Style/ArrayJoin

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.20

0.31

Checks for uses of "*" as a substitute for join.

Not all cases can reliably checked, due to Ruby’s dynamic types, so we consider only cases when the first argument is an array literal or the second is a string literal.

Examples

# bad
%w(foo bar baz) * ","

# good
%w(foo bar baz).join(",")

Style/AsciiComments

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.9

1.21

Checks for non-ascii (non-English) characters in comments. You could set an array of allowed non-ascii chars in AllowedChars attribute (copyright notice "©" by default).

Examples

# bad
# Translates from English to 日本語。

# good
# Translates from English to Japanese

Configurable attributes

Name Default value Configurable values

AllowedChars

©

Array

Style/Attr

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.12

Checks for uses of Module#attr.

Examples

# bad - creates a single attribute accessor (deprecated in Ruby 1.9)
attr :something, true
attr :one, :two, :three # behaves as attr_reader

# good
attr_accessor :something
attr_reader :one, :two, :three

Style/AutoResourceCleanup

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.30

-

Checks for cases when you could use a block accepting version of a method that does automatic resource cleanup.

Examples

# bad
f = File.open('file')

# good
File.open('file') do |f|
  # ...
end

# bad
f = Tempfile.open('temp')

# good
Tempfile.open('temp') do |f|
  # ...
end

Style/BarePercentLiterals

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.25

-

Checks if usage of %() or %Q() matches configuration.

Examples

EnforcedStyle: bare_percent (default)

# bad
%Q(He said: "#{greeting}")
%q{She said: 'Hi'}

# good
%(He said: "#{greeting}")
%{She said: 'Hi'}

EnforcedStyle: percent_q

# bad
%|He said: "#{greeting}"|
%/She said: 'Hi'/

# good
%Q|He said: "#{greeting}"|
%q/She said: 'Hi'/

Configurable attributes

Name Default value Configurable values

EnforcedStyle

bare_percent

percent_q, bare_percent

Style/BeginBlock

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.9

-

Checks for BEGIN blocks.

Examples

# bad
BEGIN { test }

Style/BisectedAttrAccessor

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.87

-

Checks for places where attr_reader and attr_writer for the same method can be combined into single attr_accessor.

Examples

# bad
class Foo
  attr_reader :bar
  attr_writer :bar
end

# good
class Foo
  attr_accessor :bar
end

Style/BitwisePredicate

Required Ruby version: 2.5
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.68

-

Prefer bitwise predicate methods over direct comparison operations.

Safety

This cop is unsafe, as it can produce false positives if the receiver is not an Integer object.

Examples

# bad - checks any set bits
(variable & flags).positive?

# good
variable.anybits?(flags)

# bad - checks all set bits
(variable & flags) == flags

# good
variable.allbits?(flags)

# bad - checks no set bits
(variable & flags).zero?

# good
variable.nobits?(flags)

Style/BlockComments

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.23

Looks for uses of block comments (=begin…​=end).

Examples

# bad
=begin
Multiple lines
of comments...
=end

# good
# Multiple lines
# of comments...

Style/BlockDelimiters

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.30

0.35

Check for uses of braces or do/end around single line or multi-line blocks.

Methods that can be either procedural or functional and cannot be categorised from their usage alone is ignored. lambda, proc, and it are their defaults. Additional methods can be added to the AllowedMethods.

Examples

EnforcedStyle: line_count_based (default)

# bad - single line block
items.each do |item| item / 5 end

# good - single line block
items.each { |item| item / 5 }

# bad - multi-line block
things.map { |thing|
  something = thing.some_method
  process(something)
}

# good - multi-line block
things.map do |thing|
  something = thing.some_method
  process(something)
end

EnforcedStyle: semantic

# Prefer `do...end` over `{...}` for procedural blocks.

# return value is used/assigned
# bad
foo = map do |x|
  x
end
puts (map do |x|
  x
end)

# return value is not used out of scope
# good
map do |x|
  x
end

# Prefer `{...}` over `do...end` for functional blocks.

# return value is not used out of scope
# bad
each { |x|
  x
}

# return value is used/assigned
# good
foo = map { |x|
  x
}
map { |x|
  x
}.inspect

# The AllowBracesOnProceduralOneLiners option is allowed unless the
# EnforcedStyle is set to `semantic`. If so:

# If the AllowBracesOnProceduralOneLiners option is unspecified, or
# set to `false` or any other falsey value, then semantic purity is
# maintained, so one-line procedural blocks must use do-end, not
# braces.

# bad
collection.each { |element| puts element }

# good
collection.each do |element| puts element end

# If the AllowBracesOnProceduralOneLiners option is set to `true`, or
# any other truthy value, then one-line procedural blocks may use
# either style. (There is no setting for requiring braces on them.)

# good
collection.each { |element| puts element }

# also good
collection.each do |element| puts element end

EnforcedStyle: braces_for_chaining

# bad
words.each do |word|
  word.flip.flop
end.join("-")

# good
words.each { |word|
  word.flip.flop
}.join("-")

EnforcedStyle: always_braces

# bad
words.each do |word|
  word.flip.flop
end

# good
words.each { |word|
  word.flip.flop
}

BracesRequiredMethods: ['sig']

# Methods listed in the BracesRequiredMethods list, such as 'sig'
# in this example, will require `{...}` braces. This option takes
# precedence over all other configurations except AllowedMethods.

# bad
sig do
  params(
    foo: string,
  ).void
end
def bar(foo)
  puts foo
end

# good
sig {
  params(
    foo: string,
  ).void
}
def bar(foo)
  puts foo
end

AllowedMethods: ['lambda', 'proc', 'it' ] (default)

# good
foo = lambda do |x|
  puts "Hello, #{x}"
end

foo = lambda do |x|
  x * 100
end

AllowedPatterns: [] (default)

# bad
things.map { |thing|
  something = thing.some_method
  process(something)
}

AllowedPatterns: ['map']

# good
things.map { |thing|
  something = thing.some_method
  process(something)
}

Configurable attributes

Name Default value Configurable values

EnforcedStyle

line_count_based

line_count_based, semantic, braces_for_chaining, always_braces

ProceduralMethods

benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object

Array

FunctionalMethods

let, let!, subject, watch

Array

AllowedMethods

lambda, proc, it

Array

AllowedPatterns

[]

Array

AllowBracesOnProceduralOneLiners

false

Boolean

BracesRequiredMethods

[]

Array

Style/CaseEquality

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.89

If AllowOnSelfClass option is enabled, the cop will ignore violations when the receiver of the case equality operator is self.class. Note intermediate variables are not accepted.

Examples

# bad
(1..100) === 7
/something/ === some_string

# good
something.is_a?(Array)
(1..100).include?(7)
/something/.match?(some_string)

AllowOnConstant: false (default)

# bad
Array === something

AllowOnConstant: true

# good
Array === something

AllowOnSelfClass: false (default)

# bad
self.class === something

AllowOnSelfClass: true

# good
self.class === something

Configurable attributes

Name Default value Configurable values

AllowOnConstant

false

Boolean

AllowOnSelfClass

false

Boolean

Style/CaseLikeIf

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.88

1.48

Identifies places where if-elsif constructions can be replaced with case-when.

Safety

This cop is unsafe. case statements use === for equality, so if the original conditional used a different equality operator, the behavior may be different.

Examples

MinBranchesCount: 3 (default)

# bad
if status == :active
  perform_action
elsif status == :inactive || status == :hibernating
  check_timeout
elsif status == :invalid
  report_invalid
else
  final_action
end

# good
case status
when :active
  perform_action
when :inactive, :hibernating
  check_timeout
when :invalid
  report_invalid
else
  final_action
end

MinBranchesCount: 4

# good
if status == :active
  perform_action
elsif status == :inactive || status == :hibernating
  check_timeout
elsif status == :invalid
  report_invalid
else
  final_action
end

Configurable attributes

Name Default value Configurable values

MinBranchesCount

3

Integer

Style/CharacterLiteral

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

-

Checks for uses of the character literal ?x. Starting with Ruby 1.9 character literals are essentially one-character strings, so this syntax is mostly redundant at this point.

? character literal can be used to express meta and control character. That’s a good use case of ? literal so it doesn’t count it as an offense.

Examples

# bad
?x

# good
'x'

# good - control & meta escapes
?\C-\M-d
"\C-\M-d" # same as above

Style/ClassAndModuleChildren

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.19

-

Checks the style of children definitions at classes and modules. Basically there are two different styles:

The compact style is only forced for classes/modules with one child.

Safety

Autocorrection is unsafe.

Moving from compact to nested children requires knowledge of whether the outer parent is a module or a class. Moving from nested to compact requires verification that the outer parent is defined elsewhere. RuboCop does not have the knowledge to perform either operation safely and thus requires manual oversight.

Examples

EnforcedStyle: nested (default)

# good
# have each child on its own line
class Foo
  class Bar
  end
end

EnforcedStyle: compact

# good
# combine definitions as much as possible
class Foo::Bar
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

nested

nested, compact

Style/ClassCheck

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.24

-

Enforces consistent use of Object#is_a? or Object#kind_of?.

Examples

EnforcedStyle: is_a? (default)

# bad
var.kind_of?(Date)
var.kind_of?(Integer)

# good
var.is_a?(Date)
var.is_a?(Integer)

EnforcedStyle: kind_of?

# bad
var.is_a?(Time)
var.is_a?(String)

# good
var.kind_of?(Time)
var.kind_of?(String)

Configurable attributes

Name Default value Configurable values

EnforcedStyle

is_a?

is_a?, kind_of?

Style/ClassEqualityComparison

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.93

1.57

Enforces the use of Object#instance_of? instead of class comparison for equality. ==, equal?, and eql? custom method definitions are allowed by default. These are customizable with AllowedMethods option.

Safety

This cop’s autocorrection is unsafe because there is no guarantee that the constant Foo exists when autocorrecting var.class.name == 'Foo' to var.instance_of?(Foo).

Examples

# bad
var.class == Date
var.class.equal?(Date)
var.class.eql?(Date)
var.class.name == 'Date'

# good
var.instance_of?(Date)

AllowedMethods: ['==', 'equal?', 'eql?'] (default)

# good
def ==(other)
  self.class == other.class && name == other.name
end

def equal?(other)
  self.class.equal?(other.class) && name.equal?(other.name)
end

def eql?(other)
  self.class.eql?(other.class) && name.eql?(other.name)
end

AllowedPatterns: [] (default)

# bad
def eq(other)
  self.class.eq(other.class) && name.eq(other.name)
end

AllowedPatterns: ['eq']

# good
def eq(other)
  self.class.eq(other.class) && name.eq(other.name)
end

Configurable attributes

Name Default value Configurable values

AllowedMethods

==, equal?, eql?

Array

AllowedPatterns

[]

Array

Style/ClassMethods

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.20

Checks for uses of the class/module name instead of self, when defining class/module methods.

Examples

# bad
class SomeClass
  def SomeClass.class_method
    # ...
  end
end

# good
class SomeClass
  def self.class_method
    # ...
  end
end

Style/ClassMethodsDefinitions

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.89

-

Enforces using def self.method_name or class << self to define class methods.

Examples

EnforcedStyle: def_self (default)

# bad
class SomeClass
  class << self
    attr_accessor :class_accessor

    def class_method
      # ...
    end
  end
end

# good
class SomeClass
  def self.class_method
    # ...
  end

  class << self
    attr_accessor :class_accessor
  end
end

# good - contains private method
class SomeClass
  class << self
    attr_accessor :class_accessor

    private

    def private_class_method
      # ...
    end
  end
end

EnforcedStyle: self_class

# bad
class SomeClass
  def self.class_method
    # ...
  end
end

# good
class SomeClass
  class << self
    def class_method
      # ...
    end
  end
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

def_self

def_self, self_class

Style/ClassVars

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.13

-

Checks for uses of class variables. Offenses are signaled only on assignment to class variables to reduce the number of offenses that would be reported.

You have to be careful when setting a value for a class variable; if a class has been inherited, changing the value of a class variable also affects the inheriting classes. This means that it’s almost always better to use a class instance variable instead.

Examples

# bad
class A
  @@test = 10
end

class A
  def self.test(name, value)
    class_variable_set("@@#{name}", value)
  end
end

class A; end
A.class_variable_set(:@@test, 10)

# good
class A
  @test = 10
end

class A
  def test
    @@test # you can access class variable without offense
  end
end

class A
  def self.test(name)
    class_variable_get("@@#{name}") # you can access without offense
  end
end

Style/CollectionCompact

Required Ruby version: 2.4
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.2

1.3

Checks for places where custom logic on rejection nils from arrays and hashes can be replaced with {Array,Hash}#{compact,compact!}.

Safety

It is unsafe by default because false positives may occur in the nil check of block arguments to the receiver object. Additionally, we can’t know the type of the receiver object for sure, which may result in false positives as well.

For example, [[1, 2], [3, nil]].reject { |first, second| second.nil? } and [[1, 2], [3, nil]].compact are not compatible. This will work fine when the receiver is a hash object.

Examples

# bad
array.reject(&:nil?)
array.reject { |e| e.nil? }
array.select { |e| !e.nil? }
array.filter { |e| !e.nil? }
array.grep_v(nil)
array.grep_v(NilClass)

# good
array.compact

# bad
hash.reject!(&:nil?)
hash.reject! { |k, v| v.nil? }
hash.select! { |k, v| !v.nil? }
hash.filter! { |k, v| !v.nil? }

# good
hash.compact!

AllowedReceivers: ['params']

# good
params.reject(&:nil?)

Configurable attributes

Name Default value Configurable values

AllowedReceivers

[]

Array

Style/CollectionMethods

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

No

Always (Unsafe)

0.9

1.7

Enforces the use of consistent method names from the Enumerable module.

You can customize the mapping from undesired method to desired method.

e.g. to use detect over find:

Style/CollectionMethods:
  PreferredMethods:
    find: detect

Safety

This cop is unsafe because it finds methods by name, without actually being able to determine if the receiver is an Enumerable or not, so this cop may register false positives.

Examples

# These examples are based on the default mapping for `PreferredMethods`.

# bad
items.collect
items.collect!
items.collect_concat
items.inject
items.detect
items.find_all
items.member?

# good
items.map
items.map!
items.flat_map
items.reduce
items.find
items.select
items.include?

Configurable attributes

Name Default value Configurable values

PreferredMethods

{"collect"⇒"map", "collect!"⇒"map!", "collect_concat"⇒"flat_map", "inject"⇒"reduce", "detect"⇒"find", "find_all"⇒"select", "member?"⇒"include?"}

MethodsAcceptingSymbol

inject, reduce

Array

Style/ColonMethodCall

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

-

Checks for methods invoked via the :: operator instead of the . operator (like FileUtils::rmdir instead of FileUtils.rmdir).

Examples

# bad
Timeout::timeout(500) { do_something }
FileUtils::rmdir(dir)
Marshal::dump(obj)

# good
Timeout.timeout(500) { do_something }
FileUtils.rmdir(dir)
Marshal.dump(obj)

Style/ColonMethodDefinition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.52

-

Checks for class methods that are defined using the :: operator instead of the . operator.

Examples

# bad
class Foo
  def self::bar
  end
end

# good
class Foo
  def self.bar
  end
end

Style/CombinableDefined

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.68

-

Checks for multiple defined? calls joined by && that can be combined into a single defined?.

When checking that a nested constant or chained method is defined, it is not necessary to check each ancestor or component of the chain.

Examples

# bad
defined?(Foo) && defined?(Foo::Bar) && defined?(Foo::Bar::Baz)

# good
defined?(Foo::Bar::Baz)

# bad
defined?(foo) && defined?(foo.bar) && defined?(foo.bar.baz)

# good
defined?(foo.bar.baz)

Style/CombinableLoops

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.90

-

Checks for places where multiple consecutive loops over the same data can be combined into a single loop. It is very likely that combining them will make the code more efficient and more concise.

Autocorrection is not applied when the block variable names differ in separate loops, as it is impossible to determine which variable name should be prioritized.

Safety

The cop is unsafe, because the first loop might modify state that the second loop depends on; these two aren’t combinable.

Examples

# bad
def method
  items.each do |item|
    do_something(item)
  end

  items.each do |item|
    do_something_else(item)
  end
end

# good
def method
  items.each do |item|
    do_something(item)
    do_something_else(item)
  end
end

# bad
def method
  for item in items do
    do_something(item)
  end

  for item in items do
    do_something_else(item)
  end
end

# good
def method
  for item in items do
    do_something(item)
    do_something_else(item)
  end
end

# good
def method
  each_slice(2) { |slice| do_something(slice) }
  each_slice(3) { |slice| do_something(slice) }
end

Style/CommandLiteral

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.30

-

Enforces using `` or %x around command literals.

Examples

EnforcedStyle: backticks (default)

# bad
folders = %x(find . -type d).split

# bad
%x(
  ln -s foo.example.yml foo.example
  ln -s bar.example.yml bar.example
)

# good
folders = `find . -type d`.split

# good
`
  ln -s foo.example.yml foo.example
  ln -s bar.example.yml bar.example
`

EnforcedStyle: mixed

# bad
folders = %x(find . -type d).split

# bad
`
  ln -s foo.example.yml foo.example
  ln -s bar.example.yml bar.example
`

# good
folders = `find . -type d`.split

# good
%x(
  ln -s foo.example.yml foo.example
  ln -s bar.example.yml bar.example
)

EnforcedStyle: percent_x

# bad
folders = `find . -type d`.split

# bad
`
  ln -s foo.example.yml foo.example
  ln -s bar.example.yml bar.example
`

# good
folders = %x(find . -type d).split

# good
%x(
  ln -s foo.example.yml foo.example
  ln -s bar.example.yml bar.example
)

AllowInnerBackticks: false (default)

# If `false`, the cop will always recommend using `%x` if one or more
# backticks are found in the command string.

# bad
`echo \`ls\``

# good
%x(echo `ls`)

AllowInnerBackticks: true

# good
`echo \`ls\``

Configurable attributes

Name Default value Configurable values

EnforcedStyle

backticks

backticks, percent_x, mixed

AllowInnerBackticks

false

Boolean

Style/CommentAnnotation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.10

1.20

Checks that comment annotation keywords are written according to guidelines.

Annotation keywords can be specified by overriding the cop’s Keywords configuration. Keywords are allowed to be single words or phrases.

With a multiline comment block (where each line is only a comment), only the first line will be able to register an offense, even if an annotation keyword starts another line. This is done to prevent incorrect registering of keywords (eg. review) inside a paragraph as an annotation.

Examples

RequireColon: true (default)

# bad
# TODO make better

# good
# TODO: make better

# bad
# TODO:make better

# good
# TODO: make better

# bad
# fixme: does not work

# good
# FIXME: does not work

# bad
# Optimize does not work

# good
# OPTIMIZE: does not work

RequireColon: false

# bad
# TODO: make better

# good
# TODO make better

# bad
# fixme does not work

# good
# FIXME does not work

# bad
# Optimize does not work

# good
# OPTIMIZE does not work

Configurable attributes

Name Default value Configurable values

Keywords

TODO, FIXME, OPTIMIZE, HACK, REVIEW, NOTE

Array

RequireColon

true

Boolean

Style/CommentedKeyword

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.51

1.19

Checks for comments put on the same line as some keywords. These keywords are: class, module, def, begin, end.

Note that some comments (:nodoc:, :yields:, rubocop:disable and rubocop:todo) and RBS::Inline annotation comments are allowed.

Autocorrection removes comments from end keyword and keeps comments for class, module, def and begin above the keyword.

Safety

Autocorrection is unsafe because it may remove a comment that is meaningful.

Examples

# bad
if condition
  statement
end # end if

# bad
class X # comment
  statement
end

# bad
def x; end # comment

# good
if condition
  statement
end

# good
class X # :nodoc:
  y
end

Style/ComparableClamp

Required Ruby version: 2.4
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.44

-

Enforces the use of Comparable#clamp instead of comparison by minimum and maximum.

This cop supports autocorrection for if/elsif/else bad style only. Because ArgumentError occurs if the minimum and maximum of clamp arguments are reversed. When these are variables, it is not possible to determine which is the minimum and maximum:

[1, [2, 3].max].min # => 1
1.clamp(3, 1)       # => min argument must be smaller than max argument (ArgumentError)

Examples

# bad
[[x, low].max, high].min

# bad
if x < low
  low
elsif high < x
  high
else
  x
end

# good
x.clamp(low, high)

Style/ConcatArrayLiterals

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.41

-

Enforces the use of Array#push(item) instead of Array#concat([item]) to avoid redundant array literals.

Safety

This cop is unsafe, as it can produce false positives if the receiver is not an Array object.

Examples

# bad
list.concat([foo])
list.concat([bar, baz])
list.concat([qux, quux], [corge])

# good
list.push(foo)
list.push(bar, baz)
list.push(qux, quux, corge)

Style/ConditionalAssignment

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.36

0.47

Check for if and case statements where each branch is used for both the assignment and comparison of the same variable when using the return of the condition can be used instead.

Examples

EnforcedStyle: assign_to_condition (default)

# bad
if foo
  bar = 1
else
  bar = 2
end

case foo
when 'a'
  bar += 1
else
  bar += 2
end

if foo
  some_method
  bar = 1
else
  some_other_method
  bar = 2
end

# good
bar = if foo
        1
      else
        2
      end

bar += case foo
       when 'a'
         1
       else
         2
       end

bar << if foo
         some_method
         1
       else
         some_other_method
         2
       end

EnforcedStyle: assign_inside_condition

# bad
bar = if foo
        1
      else
        2
      end

bar += case foo
       when 'a'
         1
       else
         2
       end

bar << if foo
         some_method
         1
       else
         some_other_method
         2
       end

# good
if foo
  bar = 1
else
  bar = 2
end

case foo
when 'a'
  bar += 1
else
  bar += 2
end

if foo
  some_method
  bar = 1
else
  some_other_method
  bar = 2
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

assign_to_condition

assign_to_condition, assign_inside_condition

SingleLineConditionsOnly

true

Boolean

IncludeTernaryExpressions

true

Boolean

Style/ConstantVisibility

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.66

1.10

Checks that constants defined in classes and modules have an explicit visibility declaration. By default, Ruby makes all class- and module constants public, which litters the public API of the class or module. Explicitly declaring a visibility makes intent more clear, and prevents outside actors from touching private state.

Examples

# bad
class Foo
  BAR = 42
  BAZ = 43
end

# good
class Foo
  BAR = 42
  private_constant :BAR

  BAZ = 43
  public_constant :BAZ
end

IgnoreModules: false (default)

# bad
class Foo
  MyClass = Struct.new()
end

# good
class Foo
  MyClass = Struct.new()
  public_constant :MyClass
end

IgnoreModules: true

# good
class Foo
  MyClass = Struct.new()
end

Configurable attributes

Name Default value Configurable values

IgnoreModules

false

Boolean

Style/Copyright

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.30

-

Check that a copyright notice was given in each source file.

The default regexp for an acceptable copyright notice can be found in config/default.yml. The default can be changed as follows:

Style/Copyright:
  Notice: '^Copyright (\(c\) )?2\d{3} Acme Inc'

This regex string is treated as an unanchored regex. For each file that RuboCop scans, a comment that matches this regex must be found or an offense is reported.

Configurable attributes

Name Default value Configurable values

Notice

^Copyright (\(c\) )?2[0-9]{3} .+

String

AutocorrectNotice

``

String

Style/DataInheritance

Required Ruby version: 3.2
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always (Unsafe)

1.49

1.51

Checks for inheritance from Data.define to avoid creating the anonymous parent class.

Safety

Autocorrection is unsafe because it will change the inheritance tree (e.g. return value of Module#ancestors) of the constant.

Examples

# bad
class Person < Data.define(:first_name, :last_name)
  def age
    42
  end
end

# good
Person = Data.define(:first_name, :last_name) do
  def age
    42
  end
end

Style/DateTime

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always (Unsafe)

0.51

0.92

Checks for consistent usage of the DateTime class over the Time class. This cop is disabled by default since these classes, although highly overlapping, have particularities that make them not replaceable in certain situations when dealing with multiple timezones and/or DST.

Safety

Autocorrection is not safe, because DateTime and Time do not have exactly the same behavior, although in most cases the autocorrection will be fine.

Examples

# bad - uses `DateTime` for current time
DateTime.now

# good - uses `Time` for current time
Time.now

# bad - uses `DateTime` for modern date
DateTime.iso8601('2016-06-29')

# good - uses `Time` for modern date
Time.iso8601('2016-06-29')

# good - uses `DateTime` with start argument for historical date
DateTime.iso8601('1751-04-23', Date::ENGLAND)

AllowCoercion: false (default)

# bad - coerces to `DateTime`
something.to_datetime

# good - coerces to `Time`
something.to_time

AllowCoercion: true

# good
something.to_datetime

# good
something.to_time

Configurable attributes

Name Default value Configurable values

AllowCoercion

false

Boolean

Style/DefWithParentheses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.12

Checks for parentheses in the definition of a method, that does not take any arguments. Both instance and class/singleton methods are checked.

Examples

# bad
def foo()
  do_something
end

# good
def foo
  do_something
end

# bad
def foo() = do_something

# good
def foo = do_something

# good (without parentheses it's a syntax error)
def foo() do_something end

# bad
def Baz.foo()
  do_something
end

# good
def Baz.foo
  do_something
end

Style/Dir

Required Ruby version: 2.0
Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.50

-

Checks for places where the #_\_dir\_\_ method can replace more complex constructs to retrieve a canonicalized absolute path to the current file.

Examples

# bad
path = File.expand_path(File.dirname(__FILE__))

# bad
path = File.dirname(File.realpath(__FILE__))

# good
path = __dir__

Style/DirEmpty

Required Ruby version: 2.4
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.48

-

Prefer to use Dir.empty?('path/to/dir') when checking if a directory is empty.

Examples

# bad
Dir.entries('path/to/dir').size == 2
Dir.children('path/to/dir').empty?
Dir.children('path/to/dir').size == 0
Dir.each_child('path/to/dir').none?

# good
Dir.empty?('path/to/dir')

Style/DisableCopsWithinSourceCodeDirective

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.82

1.9

Detects comments to enable/disable RuboCop. This is useful if want to make sure that every RuboCop error gets fixed and not quickly disabled with a comment.

Specific cops can be allowed with the AllowedCops configuration. Note that if this configuration is set, rubocop:disable all is still disallowed.

Examples

# bad
# rubocop:disable Metrics/AbcSize
def foo
end
# rubocop:enable Metrics/AbcSize

# good
def foo
end

AllowedCops: [Metrics/AbcSize]

# good
# rubocop:disable Metrics/AbcSize
def foo
end
# rubocop:enable Metrics/AbcSize

Configurable attributes

Name Default value Configurable values

AllowedCops

[]

Array

Style/DocumentDynamicEvalDefinition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

No

1.1

1.3

When using class_eval (or other eval) with string interpolation, add a comment block showing its appearance if interpolated (a practice used in Rails code).

Examples

# from activesupport/lib/active_support/core_ext/string/output_safety.rb

# bad
UNSAFE_STRING_METHODS.each do |unsafe_method|
  if 'String'.respond_to?(unsafe_method)
    class_eval <<-EOT, __FILE__, __LINE__ + 1
      def #{unsafe_method}(*params, &block)
        to_str.#{unsafe_method}(*params, &block)
      end

      def #{unsafe_method}!(*params)
        @dirty = true
        super
      end
    EOT
  end
end

# good, inline comments in heredoc
UNSAFE_STRING_METHODS.each do |unsafe_method|
  if 'String'.respond_to?(unsafe_method)
    class_eval <<-EOT, __FILE__, __LINE__ + 1
      def #{unsafe_method}(*params, &block)       # def capitalize(*params, &block)
        to_str.#{unsafe_method}(*params, &block)  #   to_str.capitalize(*params, &block)
      end                                         # end

      def #{unsafe_method}!(*params)              # def capitalize!(*params)
        @dirty = true                             #   @dirty = true
        super                                     #   super
      end                                         # end
    EOT
  end
end

# good, block comments in heredoc
class_eval <<-EOT, __FILE__, __LINE__ + 1
  # def capitalize!(*params)
  #   @dirty = true
  #   super
  # end

  def #{unsafe_method}!(*params)
    @dirty = true
    super
  end
EOT

# good, block comments before heredoc
class_eval(
  # def capitalize!(*params)
  #   @dirty = true
  #   super
  # end

  <<-EOT, __FILE__, __LINE__ + 1
    def #{unsafe_method}!(*params)
      @dirty = true
      super
    end
  EOT
)

# bad - interpolated string without comment
class_eval("def #{unsafe_method}!(*params); end")

# good - with inline comment or replace it with block comment using heredoc
class_eval("def #{unsafe_method}!(*params); end # def capitalize!(*params); end")

Style/Documentation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.9

-

Checks for missing top-level documentation of classes and modules. Classes with no body are exempt from the check and so are namespace modules - modules that have nothing in their bodies except classes, other modules, constant definitions or constant visibility declarations.

The documentation requirement is annulled if the class or module has a :nodoc: comment next to it. Likewise, :nodoc: all does the same for all its children.

Examples

# bad
class Person
  # ...
end

module Math
end

# good
# Description/Explanation of Person class
class Person
  # ...
end

# allowed
# Class without body
class Person
end

# Namespace - A namespace can be a class or a module
# Containing a class
module Namespace
  # Description/Explanation of Person class
  class Person
    # ...
  end
end

# Containing constant visibility declaration
module Namespace
  class Private
  end

  private_constant :Private
end

# Containing constant definition
module Namespace
  Public = Class.new
end

# Macro calls
module Namespace
  extend Foo
end

AllowedConstants: ['ClassMethods']

# good
module A
  module ClassMethods
    # ...
  end
end

Configurable attributes

Name Default value Configurable values

AllowedConstants

[]

Array

Exclude

spec/**/*, test/**/*

Array

Style/DocumentationMethod

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.43

-

Checks for missing documentation comment for public methods. It can optionally be configured to also require documentation for non-public methods.

This cop allows initialize method because initialize is a special method called from new. In some programming languages they are called constructor to distinguish it from method.

Examples

# bad

class Foo
  def bar
    puts baz
  end
end

module Foo
  def bar
    puts baz
  end
end

def foo.bar
  puts baz
end

# good

class Foo
  # Documentation
  def bar
    puts baz
  end
end

module Foo
  # Documentation
  def bar
    puts baz
  end
end

# Documentation
def foo.bar
  puts baz
end

RequireForNonPublicMethods: false (default)

# good
class Foo
  protected
  def do_something
  end
end

class Foo
  private
  def do_something
  end
end

RequireForNonPublicMethods: true

# bad
class Foo
  protected
  def do_something
  end
end

class Foo
  private
  def do_something
  end
end

# good
class Foo
  protected
  # Documentation
  def do_something
  end
end

class Foo
  private
  # Documentation
  def do_something
  end
end

AllowedMethods: ['method_missing', 'respond_to_missing?']

# good
class Foo
  def method_missing(name, *args)
  end

  def respond_to_missing?(symbol, include_private)
  end
end

Configurable attributes

Name Default value Configurable values

AllowedMethods

[]

Array

Exclude

spec/**/*, test/**/*

Array

RequireForNonPublicMethods

false

Boolean

Style/DoubleCopDisableDirective

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.73

-

Detects double disable comments on one line. This is mostly to catch automatically generated comments that need to be regenerated.

Examples

# bad
def f # rubocop:disable Style/For # rubocop:disable Metrics/AbcSize
end

# good
# rubocop:disable Metrics/AbcSize
def f # rubocop:disable Style/For
end
# rubocop:enable Metrics/AbcSize

# if both fit on one line
def f # rubocop:disable Style/For, Metrics/AbcSize
end

Style/DoubleNegation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.19

1.2

Checks for uses of double negation (!!) to convert something to a boolean value.

When using EnforcedStyle: allowed_in_returns, allow double negation in contexts that use boolean as a return value. When using EnforcedStyle: forbidden, double negation should be forbidden always.

when something is a boolean value !!something and !something.nil? are not the same thing. As you’re unlikely to write code that can accept values of any type this is rarely a problem in practice.

Safety

Autocorrection is unsafe when the value is false, because the result of the expression will change.

!!false     #=> false
!false.nil? #=> true

Examples

# bad
!!something

# good
!something.nil?

EnforcedStyle: allowed_in_returns (default)

# good
def foo?
  !!return_value
end

define_method :foo? do
  !!return_value
end

define_singleton_method :foo? do
  !!return_value
end

EnforcedStyle: forbidden

# bad
def foo?
  !!return_value
end

define_method :foo? do
  !!return_value
end

define_singleton_method :foo? do
  !!return_value
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

allowed_in_returns

allowed_in_returns, forbidden

Style/EachForSimpleLoop

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.41

-

Checks for loops which iterate a constant number of times, using a Range literal and #each. This can be done more readably using Integer#times.

This check only applies if the block takes no parameters.

Examples

# bad
(1..5).each { }

# good
5.times { }

# bad
(0...10).each {}

# good
10.times {}

Style/EachWithObject

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.22

0.42

Looks for inject / reduce calls where the passed in object is returned at the end and so could be replaced by each_with_object without the need to return the object at the end.

However, we can’t replace with each_with_object if the accumulator parameter is assigned to within the block.

Examples

# bad
[1, 2].inject({}) { |a, e| a[e] = e; a }

# good
[1, 2].each_with_object({}) { |e, a| a[e] = e }

Style/EmptyBlockParameter

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.52

-

Checks for pipes for empty block parameters. Pipes for empty block parameters do not cause syntax errors, but they are redundant.

Examples

# bad
a do ||
  do_something
end

# bad
a { || do_something }

# good
a do
end

# good
a { do_something }

Style/EmptyCaseCondition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.40

-

Checks for case statements with an empty condition.

Examples

# bad:
case
when x == 0
  puts 'x is 0'
when y == 0
  puts 'y is 0'
else
  puts 'neither is 0'
end

# good:
if x == 0
  puts 'x is 0'
elsif y == 0
  puts 'y is 0'
else
  puts 'neither is 0'
end

# good: (the case condition node is not empty)
case n
when 0
  puts 'zero'
when 1
  puts 'one'
else
  puts 'more'
end

Style/EmptyElse

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Command-line only

0.28

1.61

Checks for empty else-clauses, possibly including comments and/or an explicit nil depending on the EnforcedStyle.

Examples

EnforcedStyle: both (default)

# warn on empty else and else with nil in it

# bad
if condition
  statement
else
  nil
end

# bad
if condition
  statement
else
end

# good
if condition
  statement
else
  statement
end

# good
if condition
  statement
end

EnforcedStyle: empty

# warn only on empty else

# bad
if condition
  statement
else
end

# good
if condition
  statement
else
  nil
end

# good
if condition
  statement
else
  statement
end

# good
if condition
  statement
end

EnforcedStyle: nil

# warn on else with nil in it

# bad
if condition
  statement
else
  nil
end

# good
if condition
  statement
else
end

# good
if condition
  statement
else
  statement
end

# good
if condition
  statement
end

AllowComments: false (default)

# bad
if condition
  statement
else
  # something comment
  nil
end

# bad
if condition
  statement
else
  # something comment
end

AllowComments: true

# good
if condition
  statement
else
  # something comment
  nil
end

# good
if condition
  statement
else
  # something comment
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

both

empty, nil, both

AllowComments

false

Boolean

Style/EmptyHeredoc

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Command-line only

1.32

1.61

Checks for using empty heredoc to reduce redundancy.

Examples

# bad
<<~EOS
EOS

<<-EOS
EOS

<<EOS
EOS

# good
''

# bad
do_something(<<~EOS)
EOS

do_something(<<-EOS)
EOS

do_something(<<EOS)
EOS

# good
do_something('')

Style/EmptyLambdaParameter

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.52

-

Checks for parentheses for empty lambda parameters. Parentheses for empty lambda parameters do not cause syntax errors, but they are redundant.

Examples

# bad
-> () { do_something }

# good
-> { do_something }

# good
-> (arg) { do_something(arg) }

Style/EmptyLiteral

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.12

Checks for the use of a method, the result of which would be a literal, like an empty array, hash, or string.

Examples

# bad
a = Array.new
a = Array[]
h = Hash.new
h = Hash[]
s = String.new

# good
a = []
h = {}
s = ''

Style/EmptyMethod

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Command-line only

0.46

1.61

Checks for the formatting of empty method definitions. By default it enforces empty method definitions to go on a single line (compact style), but it can be configured to enforce the end to go on its own line (expanded style).

A method definition is not considered empty if it contains comments.
Autocorrection will not be applied for the compact style if the resulting code is longer than the Max configuration for Layout/LineLength, but an offense will still be registered.

Examples

EnforcedStyle: compact (default)

# bad
def foo(bar)
end

def self.foo(bar)
end

# good
def foo(bar); end

def foo(bar)
  # baz
end

def self.foo(bar); end

EnforcedStyle: expanded

# bad
def foo(bar); end

def self.foo(bar); end

# good
def foo(bar)
end

def self.foo(bar)
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

compact

compact, expanded

Style/Encoding

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.50

Checks ensures source files have no utf-8 encoding comments.

Examples

# bad
# encoding: UTF-8
# coding: UTF-8
# -*- coding: UTF-8 -*-

Style/EndBlock

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.81

Checks for END blocks.

Examples

# bad
END { puts 'Goodbye!' }

# good
at_exit { puts 'Goodbye!' }

Style/EndlessMethod

Required Ruby version: 3.0
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.8

-

Checks for endless methods.

It can enforce either the use of endless methods definitions for single-lined method bodies, or disallow endless methods.

Other method definition types are not considered by this cop.

The supported styles are:

  • allow_single_line (default) - only single line endless method definitions are allowed.

  • allow_always - all endless method definitions are allowed.

  • disallow - all endless method definitions are disallowed.

Incorrect endless method definitions will always be corrected to a multi-line definition.

Examples

EnforcedStyle: allow_single_line (default)

# good
def my_method() = x

# bad, multi-line endless method
def my_method() = x.foo
                   .bar
                   .baz

EnforcedStyle: allow_always

# good
def my_method() = x

# good
def my_method() = x.foo
                   .bar
                   .baz

EnforcedStyle: disallow

# bad
def my_method() = x

# bad
def my_method() = x.foo
                   .bar
                   .baz

Configurable attributes

Name Default value Configurable values

EnforcedStyle

allow_single_line

allow_single_line, allow_always, disallow

Style/EnvHome

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.29

-

Checks for consistent usage of ENV['HOME']. If nil is used as the second argument of ENV.fetch, it is treated as a bad case like ENV[].

Safety

The cop is unsafe because the result when nil is assigned to ENV['HOME'] changes:

ENV['HOME'] = nil
ENV['HOME'] # => nil
Dir.home    # => '/home/foo'

Examples

# bad
ENV['HOME']
ENV.fetch('HOME', nil)

# good
Dir.home

# good
ENV.fetch('HOME', default)

Style/EvalWithLocation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.52

-

Ensures that eval methods (eval, instance_eval, class_eval and module_eval) are given filename and line number values (_\_FILE\__ and \__LINE\_\_). This data is used to ensure that any errors raised within the evaluated code will be given the correct identification in a backtrace.

The cop also checks that the line number given relative to _\_LINE\_\_ is correct.

This cop will autocorrect incorrect or missing filename and line number values. However, if eval is called without a binding argument, the cop will not attempt to automatically add a binding, or add filename and line values.

This cop works only when a string literal is given as a code string. No offense is reported if a string variable is given as below:
code = <<-RUBY
  def do_something
  end
RUBY
eval code # not checked.

Examples

# bad
eval <<-RUBY
  def do_something
  end
RUBY

# bad
C.class_eval <<-RUBY
  def do_something
  end
RUBY

# good
eval <<-RUBY, binding, __FILE__, __LINE__ + 1
  def do_something
  end
RUBY

# good
C.class_eval <<-RUBY, __FILE__, __LINE__ + 1
  def do_something
  end
RUBY

Style/EvenOdd

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.12

0.29

Checks for places where Integer#even? or Integer#odd? can be used.

Examples

# bad
if x % 2 == 0
end

# good
if x.even?
end

Style/ExactRegexpMatch

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.51

-

Checks for exact regexp match inside Regexp literals.

Examples

# bad
string =~ /\Astring\z/
string === /\Astring\z/
string.match(/\Astring\z/)
string.match?(/\Astring\z/)

# good
string == 'string'

# bad
string !~ /\Astring\z/

# good
string != 'string'

Style/ExpandPathArguments

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.53

-

Checks for use of the File.expand_path arguments. Likewise, it also checks for the Pathname.new argument.

Contrastive bad case and good case are alternately shown in the following examples.

Examples

# bad
File.expand_path('..', __FILE__)

# good
File.expand_path(__dir__)

# bad
File.expand_path('../..', __FILE__)

# good
File.expand_path('..', __dir__)

# bad
File.expand_path('.', __FILE__)

# good
File.expand_path(__FILE__)

# bad
Pathname(__FILE__).parent.expand_path

# good
Pathname(__dir__).expand_path

# bad
Pathname.new(__FILE__).parent.expand_path

# good
Pathname.new(__dir__).expand_path

Style/ExplicitBlockArgument

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.89

1.8

Enforces the use of explicit block argument to avoid writing block literal that just passes its arguments to another block.

This cop only registers an offense if the block args match the yield args exactly.

Examples

# bad
def with_tmp_dir
  Dir.mktmpdir do |tmp_dir|
    Dir.chdir(tmp_dir) { |dir| yield dir } # block just passes arguments
  end
end

# bad
def nine_times
  9.times { yield }
end

# good
def with_tmp_dir(&block)
  Dir.mktmpdir do |tmp_dir|
    Dir.chdir(tmp_dir, &block)
  end
end

with_tmp_dir do |dir|
  puts "dir is accessible as a parameter and pwd is set: #{dir}"
end

# good
def nine_times(&block)
  9.times(&block)
end

Style/ExponentialNotation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.82

-

Enforces consistency when using exponential notation for numbers in the code (eg 1.2e4). Different styles are supported:

  • scientific which enforces a mantissa between 1 (inclusive) and 10 (exclusive).

  • engineering which enforces the exponent to be a multiple of 3 and the mantissa to be between 0.1 (inclusive) and 10 (exclusive).

  • integral which enforces the mantissa to always be a whole number without trailing zeroes.

Examples

EnforcedStyle: scientific (default)

# Enforces a mantissa between 1 (inclusive) and 10 (exclusive).

# bad
10e6
0.3e4
11.7e5
3.14e0

# good
1e7
3e3
1.17e6
3.14

EnforcedStyle: engineering

# Enforces using multiple of 3 exponents,
# mantissa should be between 0.1 (inclusive) and 1000 (exclusive)

# bad
3.2e7
0.1e5
12e5
1232e6

# good
32e6
10e3
1.2e6
1.232e9

EnforcedStyle: integral

# Enforces the mantissa to have no decimal part and no
# trailing zeroes.

# bad
3.2e7
0.1e5
120e4

# good
32e6
1e4
12e5

Configurable attributes

Name Default value Configurable values

EnforcedStyle

scientific

scientific, engineering, integral

Style/FetchEnvVar

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.28

-

Suggests ENV.fetch for the replacement of ENV[]. ENV[] silently fails and returns nil when the environment variable is unset, which may cause unexpected behaviors when the developer forgets to set it. On the other hand, ENV.fetch raises KeyError or returns the explicitly specified default value.

Examples

# bad
ENV['X']
x = ENV['X']

# good
ENV.fetch('X')
x = ENV.fetch('X')

# also good
!ENV['X']
ENV['X'].some_method # (e.g. `.nil?`)

Configurable attributes

Name Default value Configurable values

AllowedVars

[]

Array

Style/FileEmpty

Required Ruby version: 2.4
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.48

-

Prefer to use File.empty?('path/to/file') when checking if a file is empty.

Safety

This cop is unsafe, because File.size, File.read, and File.binread raise ENOENT exception when there is no file corresponding to the path, while File.empty? does not raise an exception.

Examples

# bad
File.zero?('path/to/file')
File.size('path/to/file') == 0
File.size('path/to/file') >= 0
File.size('path/to/file').zero?
File.read('path/to/file').empty?
File.binread('path/to/file') == ''
FileTest.zero?('path/to/file')

# good
File.empty?('path/to/file')
FileTest.empty?('path/to/file')

Style/FileRead

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.24

-

Favor File.(bin)read convenience methods.

Examples

# bad - text mode
File.open(filename).read
File.open(filename, &:read)
File.open(filename) { |f| f.read }
File.open(filename) do |f|
  f.read
end
File.open(filename, 'r').read
File.open(filename, 'r', &:read)
File.open(filename, 'r') do |f|
  f.read
end

# good
File.read(filename)

# bad - binary mode
File.open(filename, 'rb').read
File.open(filename, 'rb', &:read)
File.open(filename, 'rb') do |f|
  f.read
end

# good
File.binread(filename)

Style/FileWrite

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.24

-

Favor File.(bin)write convenience methods.

There are different method signatures between File.write (class method) and File#write (instance method). The following case will be allowed because static analysis does not know the contents of the splat argument:
File.open(filename, 'w') do |f|
  f.write(*objects)
end

Examples

# bad - text mode
File.open(filename, 'w').write(content)
File.open(filename, 'w') do |f|
  f.write(content)
end

# good
File.write(filename, content)

# bad - binary mode
File.open(filename, 'wb').write(content)
File.open(filename, 'wb') do |f|
  f.write(content)
end

# good
File.binwrite(filename, content)

Style/FloatDivision

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.72

1.9

Checks for division with integers coerced to floats. It is recommended to either always use fdiv or coerce one side only. This cop also provides other options for code consistency.

Safety

This cop is unsafe, because if the operand variable is a string object then .to_f will be removed and an error will occur.

a = '1.2'
b = '3.4'
a.to_f / b.to_f # Both `to_f` calls are required here

Examples

EnforcedStyle: single_coerce (default)

# bad
a.to_f / b.to_f

# good
a.to_f / b
a / b.to_f

EnforcedStyle: left_coerce

# bad
a / b.to_f
a.to_f / b.to_f

# good
a.to_f / b

EnforcedStyle: right_coerce

# bad
a.to_f / b
a.to_f / b.to_f

# good
a / b.to_f

EnforcedStyle: fdiv

# bad
a / b.to_f
a.to_f / b
a.to_f / b.to_f

# good
a.fdiv(b)

Configurable attributes

Name Default value Configurable values

EnforcedStyle

single_coerce

left_coerce, right_coerce, single_coerce, fdiv

Style/For

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.13

1.26

Looks for uses of the for keyword or each method. The preferred alternative is set in the EnforcedStyle configuration parameter. An each call with a block on a single line is always allowed.

Safety

This cop’s autocorrection is unsafe because the scope of variables is different between each and for.

Examples

EnforcedStyle: each (default)

# bad
def foo
  for n in [1, 2, 3] do
    puts n
  end
end

# good
def foo
  [1, 2, 3].each do |n|
    puts n
  end
end

EnforcedStyle: for

# bad
def foo
  [1, 2, 3].each do |n|
    puts n
  end
end

# good
def foo
  for n in [1, 2, 3] do
    puts n
  end
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

each

each, for

Style/FormatString

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.19

0.49

Enforces the use of a single string formatting utility. Valid options include Kernel#format, Kernel#sprintf, and String#%.

The detection of String#% cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal.

Autocorrection will be applied when using argument is a literal or known built-in conversion methods such as to_d, to_f, to_h, to_i, to_r, to_s, and to_sym on variables, provided that their return value is not an array. For example, when using to_s, '%s' % [1, 2, 3].to_s can be autocorrected without any incompatibility:

'%s' % [1, 2, 3]        #=> '1'
format('%s', [1, 2, 3]) #=> '[1, 2, 3]'
'%s' % [1, 2, 3].to_s   #=> '[1, 2, 3]'

Examples

EnforcedStyle: format (default)

# bad
puts sprintf('%10s', 'foo')
puts '%10s' % 'foo'

# good
puts format('%10s', 'foo')

EnforcedStyle: sprintf

# bad
puts format('%10s', 'foo')
puts '%10s' % 'foo'

# good
puts sprintf('%10s', 'foo')

EnforcedStyle: percent

# bad
puts format('%10s', 'foo')
puts sprintf('%10s', 'foo')

# good
puts '%10s' % 'foo'

Configurable attributes

Name Default value Configurable values

EnforcedStyle

format

format, sprintf, percent

Style/FormatStringToken

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.49

1.0

Use a consistent style for named format string tokens.

unannotated style cop only works for strings which are passed as arguments to those methods: printf, sprintf, format, %. The reason is that unannotated format is very similar to encoded URLs or Date/Time formatting strings.

This cop’s allowed methods can be customized with AllowedMethods. By default, there are no allowed methods.

It is allowed to contain unannotated token if the number of them is less than or equals to MaxUnannotatedPlaceholdersAllowed.

Examples

EnforcedStyle: annotated (default)

# bad
format('%{greeting}', greeting: 'Hello')
format('%s', 'Hello')

# good
format('%<greeting>s', greeting: 'Hello')

EnforcedStyle: template

# bad
format('%<greeting>s', greeting: 'Hello')
format('%s', 'Hello')

# good
format('%{greeting}', greeting: 'Hello')

EnforcedStyle: unannotated

# bad
format('%<greeting>s', greeting: 'Hello')
format('%{greeting}', greeting: 'Hello')

# good
format('%s', 'Hello')

MaxUnannotatedPlaceholdersAllowed: 0

# bad
format('%06d', 10)
format('%s %s.', 'Hello', 'world')

# good
format('%<number>06d', number: 10)

MaxUnannotatedPlaceholdersAllowed: 1 (default)

# bad
format('%s %s.', 'Hello', 'world')

# good
format('%06d', 10)

AllowedMethods: [] (default)

# bad
redirect('foo/%{bar_id}')

AllowedMethods: [redirect]

# good
redirect('foo/%{bar_id}')

AllowedPatterns: [] (default)

# bad
redirect('foo/%{bar_id}')

AllowedPatterns: ['redirect']

# good
redirect('foo/%{bar_id}')

Configurable attributes

Name Default value Configurable values

EnforcedStyle

annotated

annotated, template, unannotated

MaxUnannotatedPlaceholdersAllowed

1

Integer

AllowedMethods

[]

Array

AllowedPatterns

[]

Array

Style/FrozenStringLiteralComment

Required Ruby version: 2.3
Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.36

0.79

Helps you transition from mutable string literals to frozen string literals. It will add the # frozen_string_literal: true magic comment to the top of files to enable frozen string literals. Frozen string literals may be default in future Ruby. The comment will be added below a shebang and encoding comment. The frozen string literal comment is only valid in Ruby 2.3+.

Note that the cop will accept files where the comment exists but is set to false instead of true.

To require a blank line after this comment, please see Layout/EmptyLineAfterMagicComment cop.

Safety

This cop’s autocorrection is unsafe since any strings mutations will change from being accepted to raising FrozenError, as all strings will become frozen by default, and will need to be manually refactored.

Examples

EnforcedStyle: always (default)

# The `always` style will always add the frozen string literal comment
# to a file, regardless of the Ruby version or if `freeze` or `<<` are
# called on a string literal.
# bad
module Bar
  # ...
end

# good
# frozen_string_literal: true

module Bar
  # ...
end

# good
# frozen_string_literal: false

module Bar
  # ...
end

EnforcedStyle: never

# The `never` will enforce that the frozen string literal comment does
# not exist in a file.
# bad
# frozen_string_literal: true

module Baz
  # ...
end

# good
module Baz
  # ...
end

EnforcedStyle: always_true

# The `always_true` style enforces that the frozen string literal
# comment is set to `true`. This is a stricter option than `always`
# and forces projects to use frozen string literals.
# bad
# frozen_string_literal: false

module Baz
  # ...
end

# bad
module Baz
  # ...
end

# good
# frozen_string_literal: true

module Bar
  # ...
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

always

always, always_true, never

Style/GlobalStdStream

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.89

-

Enforces the use of $stdout/$stderr/$stdin instead of STDOUT/STDERR/STDIN. STDOUT/STDERR/STDIN are constants, and while you can actually reassign (possibly to redirect some stream) constants in Ruby, you’ll get an interpreter warning if you do so.

Safety

Autocorrection is unsafe because STDOUT and $stdout may point to different objects, for example.

Examples

# bad
STDOUT.puts('hello')

hash = { out: STDOUT, key: value }

def m(out = STDOUT)
  out.puts('hello')
end

# good
$stdout.puts('hello')

hash = { out: $stdout, key: value }

def m(out = $stdout)
  out.puts('hello')
end

Style/GlobalVars

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.13

-

Looks for uses of global variables. It does not report offenses for built-in global variables. Built-in global variables are allowed by default. Additionally users can allow additional variables via the AllowedVariables option.

Note that backreferences like $1, $2, etc are not global variables.

Examples

# bad
$foo = 2
bar = $foo + 5

# good
FOO = 2
foo = 2
$stdin.read

Configurable attributes

Name Default value Configurable values

AllowedVariables

[]

Array

Style/GuardClause

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.20

1.31

Use a guard clause instead of wrapping the code inside a conditional expression

A condition with an elsif or else branch is allowed unless one of return, break, next, raise, or fail is used in the body of the conditional expression.

Autocorrect works in most cases except with if-else statements that contain logical operators such as foo || raise('exception')

Examples

# bad
def test
  if something
    work
  end
end

# good
def test
  return unless something

  work
end

# also good
def test
  work if something
end

# bad
if something
  raise 'exception'
else
  ok
end

# good
raise 'exception' if something
ok

# bad
if something
  foo || raise('exception')
else
  ok
end

# good
foo || raise('exception') if something
ok

# bad
define_method(:test) do
  if something
    work
  end
end

# good
define_method(:test) do
  return unless something

  work
end

# also good
define_method(:test) do
  work if something
end

AllowConsecutiveConditionals: false (default)

# bad
def test
  if foo?
    work
  end

  if bar?  # <- reports an offense
    work
  end
end

AllowConsecutiveConditionals: true

# good
def test
  if foo?
    work
  end

  if bar?
    work
  end
end

# bad
def test
  if foo?
    work
  end

  do_something

  if bar?  # <- reports an offense
    work
  end
end

Configurable attributes

Name Default value Configurable values

MinBodyLength

1

Integer

AllowConsecutiveConditionals

false

Boolean

Style/HashAsLastArrayItem

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.88

-

Checks for presence or absence of braces around hash literal as a last array item depending on configuration.

This cop will ignore arrays where all items are hashes, regardless of EnforcedStyle.

Examples

EnforcedStyle: braces (default)

# bad
[1, 2, one: 1, two: 2]

# good
[1, 2, { one: 1, two: 2 }]

# good
[{ one: 1 }, { two: 2 }]

EnforcedStyle: no_braces

# bad
[1, 2, { one: 1, two: 2 }]

# good
[1, 2, one: 1, two: 2]

# good
[{ one: 1 }, { two: 2 }]

Configurable attributes

Name Default value Configurable values

EnforcedStyle

braces

braces, no_braces

Style/HashConversion

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always (Unsafe)

1.10

1.55

Checks the usage of pre-2.1 Hash[args] method of converting enumerables and sequences of values to hashes.

Correction code from splat argument (Hash[*ary]) is not simply determined. For example, Hash[*ary] can be replaced with ary.each_slice(2).to_h but it will be complicated. So, AllowSplatArgument option is true by default to allow splat argument for simple code.

Safety

This cop’s autocorrection is unsafe because ArgumentError occurs if the number of elements is odd:

Hash[[[1, 2], [3]]] #=> {1=>2, 3=>nil}
[[1, 2], [5]].to_h  #=> wrong array length at 1 (expected 2, was 1) (ArgumentError)

Examples

# bad
Hash[ary]

# good
ary.to_h

# bad
Hash[key1, value1, key2, value2]

# good
{key1 => value1, key2 => value2}

AllowSplatArgument: true (default)

# good
Hash[*ary]

AllowSplatArgument: false

# bad
Hash[*ary]

Configurable attributes

Name Default value Configurable values

AllowSplatArgument

true

Boolean

Style/HashEachMethods

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.80

1.16

Checks for uses of each_key and each_value Hash methods.

If you have an array of two-element arrays, you can put parentheses around the block arguments to indicate that you’re not working with a hash, and suppress RuboCop offenses.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver is a Hash. The AllowedReceivers configuration can mitigate, but not fully resolve, this safety issue.

Examples

# bad
hash.keys.each { |k| p k }
hash.each { |k, unused_value| p k }

# good
hash.each_key { |k| p k }

# bad
hash.values.each { |v| p v }
hash.each { |unused_key, v| p v }

# good
hash.each_value { |v| p v }

AllowedReceivers: ['execute']

# good
execute(sql).keys.each { |v| p v }
execute(sql).values.each { |v| p v }

Configurable attributes

Name Default value Configurable values

AllowedReceivers

Thread.current

Array

Style/HashExcept

Required Ruby version: 3.0
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.7

1.39

Checks for usages of Hash#reject, Hash#select, and Hash#filter methods that can be replaced with Hash#except method.

This cop should only be enabled on Ruby version 3.0 or higher. (Hash#except was added in Ruby 3.0.)

For safe detection, it is limited to commonly used string and symbol comparisons when used ==. And do not check Hash#delete_if and Hash#keep_if to change receiver object.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver is a Hash or responds to the replacement method.

Examples

# bad
{foo: 1, bar: 2, baz: 3}.reject {|k, v| k == :bar }
{foo: 1, bar: 2, baz: 3}.select {|k, v| k != :bar }
{foo: 1, bar: 2, baz: 3}.filter {|k, v| k != :bar }
{foo: 1, bar: 2, baz: 3}.reject {|k, v| %i[bar].include?(k) }
{foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[bar].include?(k) }
{foo: 1, bar: 2, baz: 3}.filter {|k, v| !%i[bar].include?(k) }

# good
{foo: 1, bar: 2, baz: 3}.except(:bar)

Style/HashLikeCase

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.88

-

Checks for places where case-when represents a simple 1:1 mapping and can be replaced with a hash lookup.

Examples

MinBranchesCount: 3 (default)

# bad
case country
when 'europe'
  'http://eu.example.com'
when 'america'
  'http://us.example.com'
when 'australia'
  'http://au.example.com'
end

# good
SITES = {
  'europe'    => 'http://eu.example.com',
  'america'   => 'http://us.example.com',
  'australia' => 'http://au.example.com'
}
SITES[country]

MinBranchesCount: 4

# good
case country
when 'europe'
  'http://eu.example.com'
when 'america'
  'http://us.example.com'
when 'australia'
  'http://au.example.com'
end

Configurable attributes

Name Default value Configurable values

MinBranchesCount

3

Integer

Style/HashSyntax

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

1.67

Checks hash literal syntax.

It can enforce either the use of the class hash rocket syntax or the use of the newer Ruby 1.9 syntax (when applicable).

A separate offense is registered for each problematic pair.

The supported styles are:

  • ruby19 - forces use of the 1.9 syntax (e.g. {a: 1}) when hashes have all symbols for keys

  • hash_rockets - forces use of hash rockets for all hashes

  • no_mixed_keys - simply checks for hashes with mixed syntaxes

  • ruby19_no_mixed_keys - forces use of ruby 1.9 syntax and forbids mixed syntax hashes

This cop has EnforcedShorthandSyntax option. It can enforce either the use of the explicit hash value syntax or the use of Ruby 3.1’s hash value shorthand syntax.

The supported styles are:

  • always - forces use of the 3.1 syntax (e.g. {foo:})

  • never - forces use of explicit hash literal value

  • either - accepts both shorthand and explicit use of hash literal value

  • consistent - forces use of the 3.1 syntax only if all values can be omitted in the hash

  • either_consistent - accepts both shorthand and explicit use of hash literal value, but they must be consistent

Examples

EnforcedStyle: ruby19 (default)

# bad
{:a => 2}
{b: 1, :c => 2}

# good
{a: 2, b: 1}
{:c => 2, 'd' => 2} # acceptable since 'd' isn't a symbol
{d: 1, 'e' => 2} # technically not forbidden

EnforcedStyle: hash_rockets

# bad
{a: 1, b: 2}
{c: 1, 'd' => 5}

# good
{:a => 1, :b => 2}

EnforcedStyle: no_mixed_keys

# bad
{:a => 1, b: 2}
{c: 1, 'd' => 2}

# good
{:a => 1, :b => 2}
{c: 1, d: 2}

EnforcedStyle: ruby19_no_mixed_keys

# bad
{:a => 1, :b => 2}
{c: 2, 'd' => 3} # should just use hash rockets

# good
{a: 1, b: 2}
{:c => 3, 'd' => 4}

EnforcedShorthandSyntax: always

# bad
{foo: foo, bar: bar}

# good
{foo:, bar:}

EnforcedShorthandSyntax: never

# bad
{foo:, bar:}

# good
{foo: foo, bar: bar}

EnforcedShorthandSyntax: either (default)

# good
{foo: foo, bar: bar}

# good
{foo: foo, bar:}

# good
{foo:, bar:}

EnforcedShorthandSyntax: consistent

# bad - `foo` and `bar` values can be omitted
{foo: foo, bar: bar}

# bad - `bar` value can be omitted
{foo:, bar: bar}

# bad - mixed syntaxes
{foo:, bar: baz}

# good
{foo:, bar:}

# good - can't omit `baz`
{foo: foo, bar: baz}

EnforcedShorthandSyntax: either_consistent

# good - `foo` and `bar` values can be omitted, but they are consistent, so it's accepted
{foo: foo, bar: bar}

# bad - `bar` value can be omitted
{foo:, bar: bar}

# bad - mixed syntaxes
{foo:, bar: baz}

# good
{foo:, bar:}

# good - can't omit `baz`
{foo: foo, bar: baz}

Configurable attributes

Name Default value Configurable values

EnforcedStyle

ruby19

ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys

EnforcedShorthandSyntax

either

always, never, either, consistent, either_consistent

UseHashRocketsWithSymbolValues

false

Boolean

PreferHashRocketsForNonAlnumEndingSymbols

false

Boolean

Style/HashTransformKeys

Required Ruby version: 2.5
Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.80

0.90

Looks for uses of _.each_with_object({}) {…​}, \_.map {…​}.to_h, and Hash[\_.map {…​}] that are actually just transforming the keys of a hash, and tries to use a simpler & faster call to transform_keys instead. It should only be enabled on Ruby version 2.5 or newer. (transform_keys was added in Ruby 2.5.)

Safety

This cop is unsafe, as it can produce false positives if we are transforming an enumerable of key-value-like pairs that isn’t actually a hash, e.g.: [[k1, v1], [k2, v2], …​]

Examples

# bad
{a: 1, b: 2}.each_with_object({}) { |(k, v), h| h[foo(k)] = v }
Hash[{a: 1, b: 2}.collect { |k, v| [foo(k), v] }]
{a: 1, b: 2}.map { |k, v| [k.to_s, v] }.to_h
{a: 1, b: 2}.to_h { |k, v| [k.to_s, v] }

# good
{a: 1, b: 2}.transform_keys { |k| foo(k) }
{a: 1, b: 2}.transform_keys { |k| k.to_s }

Style/HashTransformValues

Required Ruby version: 2.4
Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.80

0.90

Looks for uses of _.each_with_object({}) {…​}, \_.map {…​}.to_h, and Hash[\_.map {…​}] that are actually just transforming the values of a hash, and tries to use a simpler & faster call to transform_values instead.

Safety

This cop is unsafe, as it can produce false positives if we are transforming an enumerable of key-value-like pairs that isn’t actually a hash, e.g.: [[k1, v1], [k2, v2], …​]

Examples

# bad
{a: 1, b: 2}.each_with_object({}) { |(k, v), h| h[k] = foo(v) }
Hash[{a: 1, b: 2}.collect { |k, v| [k, foo(v)] }]
{a: 1, b: 2}.map { |k, v| [k, v * v] }.to_h
{a: 1, b: 2}.to_h { |k, v| [k, v * v] }

# good
{a: 1, b: 2}.transform_values { |v| foo(v) }
{a: 1, b: 2}.transform_values { |v| v * v }

Style/IdenticalConditionalBranches

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.36

1.19

Checks for identical expressions at the beginning or end of each branch of a conditional expression. Such expressions should normally be placed outside the conditional expression - before or after it.

The cop is poorly named and some people might think that it actually checks for duplicated conditional branches. The name will probably be changed in a future major RuboCop release.

Safety

Autocorrection is unsafe because changing the order of method invocations may change the behavior of the code. For example:

if method_that_modifies_global_state # 1
  method_that_relies_on_global_state # 2
  foo                                # 3
else
  method_that_relies_on_global_state # 2
  bar                                # 3
end

In this example, method_that_relies_on_global_state will be moved before method_that_modifies_global_state, which changes the behavior of the program.

Examples

# bad
if condition
  do_x
  do_z
else
  do_y
  do_z
end

# good
if condition
  do_x
else
  do_y
end
do_z

# bad
if condition
  do_z
  do_x
else
  do_z
  do_y
end

# good
do_z
if condition
  do_x
else
  do_y
end

# bad
case foo
when 1
  do_x
when 2
  do_x
else
  do_x
end

# good
case foo
when 1
  do_x
  do_y
when 2
  # nothing
else
  do_x
  do_z
end

# bad
case foo
in 1
  do_x
in 2
  do_x
else
  do_x
end

# good
case foo
in 1
  do_x
  do_y
in 2
  # nothing
else
  do_x
  do_z
end

Style/IfInsideElse

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.36

1.3

If the else branch of a conditional consists solely of an if node, it can be combined with the else to become an elsif. This helps to keep the nesting level from getting too deep.

Examples

# bad
if condition_a
  action_a
else
  if condition_b
    action_b
  else
    action_c
  end
end

# good
if condition_a
  action_a
elsif condition_b
  action_b
else
  action_c
end

AllowIfModifier: false (default)

# bad
if condition_a
  action_a
else
  action_b if condition_b
end

# good
if condition_a
  action_a
elsif condition_b
  action_b
end

AllowIfModifier: true

# good
if condition_a
  action_a
else
  action_b if condition_b
end

# good
if condition_a
  action_a
elsif condition_b
  action_b
end

Configurable attributes

Name Default value Configurable values

AllowIfModifier

false

Boolean

Style/IfUnlessModifier

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.30

Checks for if and unless statements that would fit on one line if written as modifier if/unless. The cop also checks for modifier if/unless lines that exceed the maximum line length.

The maximum line length is configured in the Layout/LineLength cop. The tab size is configured in the IndentationWidth of the Layout/IndentationStyle cop.

One-line pattern matching is always allowed. To ensure that there are few cases where the match variable is not used, and to prevent oversights. The variable x becomes undefined and raises NameError when the following example is changed to the modifier form:

if [42] in [x]
  x # `x` is undefined when using modifier form.
end
It is allowed when defined? argument has an undefined value, because using the modifier form causes the following incompatibility:
unless defined?(undefined_foo)
  undefined_foo = 'default_value'
end
undefined_foo # => 'default_value'

undefined_bar = 'default_value' unless defined?(undefined_bar)
undefined_bar # => nil

Examples

# bad
if condition
  do_stuff(bar)
end

unless qux.empty?
  Foo.do_something
end

do_something_with_a_long_name(arg) if long_condition_that_prevents_code_fit_on_single_line

# good
do_stuff(bar) if condition
Foo.do_something unless qux.empty?

if long_condition_that_prevents_code_fit_on_single_line
  do_something_with_a_long_name(arg)
end

if short_condition # a long comment that makes it too long if it were just a single line
  do_something
end

Style/IfUnlessModifierOfIfUnless

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.39

0.87

Checks for if and unless statements used as modifiers of other if or unless statements.

Examples

# bad
tired? ? 'stop' : 'go faster' if running?

# bad
if tired?
  "please stop"
else
  "keep going"
end if running?

# good
if running?
  tired? ? 'stop' : 'go faster'
end

Style/IfWithBooleanLiteralBranches

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always (Unsafe)

1.9

-

Checks for redundant if with boolean literal branches. It checks only conditions to return boolean value (true or false) for safe detection. The conditions to be checked are comparison methods, predicate methods, and double negation (!!). nonzero? method is allowed by default. These are customizable with AllowedMethods option.

This cop targets only if`s with a single `elsif or else branch. The following code will be allowed, because it has two elsif branches:

if foo
  true
elsif bar > baz
  true
elsif qux > quux # Single `elsif` is warned, but two or more `elsif`s are not.
  true
else
  false
end

Safety

Autocorrection is unsafe because there is no guarantee that all predicate methods will return a boolean value. Those methods can be allowed with AllowedMethods config.

Examples

# bad
if foo == bar
  true
else
  false
end

# bad
foo == bar ? true : false

# good
foo == bar

# bad
if foo.do_something?
  true
else
  false
end

# good (but potentially an unsafe correction)
foo.do_something?

AllowedMethods: ['nonzero?'] (default)

# good
num.nonzero? ? true : false

Configurable attributes

Name Default value Configurable values

AllowedMethods

nonzero?

Array

Style/IfWithSemicolon

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.83

Checks for uses of semicolon in if statements.

Examples

# bad
result = if some_condition; something else another_thing end

# good
result = some_condition ? something : another_thing

Style/ImplicitRuntimeError

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.41

-

Checks for raise or fail statements which do not specify an explicit exception class. (This raises a RuntimeError. Some projects might prefer to use exception classes which more precisely identify the nature of the error.)

Examples

# bad
raise 'Error message here'

# good
raise ArgumentError, 'Error message here'

Style/InPatternThen

Required Ruby version: 2.7
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.16

-

Checks for in; uses in case expressions.

Examples

# bad
case expression
in pattern_a; foo
in pattern_b; bar
end

# good
case expression
in pattern_a then foo
in pattern_b then bar
end

Style/InfiniteLoop

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.26

0.61

Use Kernel#loop for infinite loops.

Safety

This cop is unsafe as the rule should not necessarily apply if the loop body might raise a StopIteration exception; contrary to other infinite loops, Kernel#loop silently rescues that and returns nil.

Examples

# bad
while true
  work
end

# good
loop do
  work
end

Style/InlineComment

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.23

-

Checks for trailing inline comments.

Examples

# good
foo.each do |f|
  # Standalone comment
  f.bar
end

# bad
foo.each do |f|
  f.bar # Trailing inline comment
end

Style/InverseMethods

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.48

-

Check for usages of not (not or !) called on a method when an inverse of that method can be used instead.

Methods that can be inverted by a not (not or !) should be defined in InverseMethods.

Methods that are inverted by inverting the return of the block that is passed to the method should be defined in InverseBlocks.

Safety

This cop is unsafe because it cannot be guaranteed that the method and its inverse method are both defined on receiver, and also are actually inverse of each other.

Examples

# bad
!foo.none?
!foo.any? { |f| f.even? }
!foo.blank?
!(foo == bar)
foo.select { |f| !f.even? }
foo.reject { |f| f != 7 }

# good
foo.none?
foo.blank?
foo.any? { |f| f.even? }
foo != bar
foo == bar
!!('foo' =~ /^\w+$/)
!(foo.class < Numeric) # Checking class hierarchy is allowed
# Blocks with guard clauses are ignored:
foo.select do |f|
  next if f.zero?
  f != 1
end

Configurable attributes

Name Default value Configurable values

InverseMethods

{:any?⇒:none?, :even?⇒:odd?, :==⇒:!=, :=⇒:!, :<⇒:>=, :>⇒:⇐}

InverseBlocks

{:select⇒:reject, :select!⇒:reject!}

Style/InvertibleUnlessCondition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

No

Always (Unsafe)

1.44

1.50

Checks for usages of unless which can be replaced by if with inverted condition. Code without unless is easier to read, but that is subjective, so this cop is disabled by default.

Methods that can be inverted should be defined in InverseMethods. Note that the relationship of inverse methods needs to be defined in both directions. For example,

InverseMethods:
  :!=: :==
  :even?: :odd?
  :odd?: :even?

will suggest both even? and odd? to be inverted, but only != (and not ==).

Safety

This cop is unsafe because it cannot be guaranteed that the method and its inverse method are both defined on receiver, and also are actually inverse of each other.

Examples

# bad (simple condition)
foo unless !bar
foo unless x != y
foo unless x >= 10
foo unless x.even?
foo unless odd?

# good
foo if bar
foo if x == y
foo if x < 10
foo if x.odd?
foo if even?

# bad (complex condition)
foo unless x != y || x.even?

# good
foo if x == y && x.odd?

# good (if)
foo if !condition

Configurable attributes

Name Default value Configurable values

InverseMethods

{:!=⇒:==, :>⇒:⇐, :⇐⇒:>, :<⇒:>=, :>=⇒:<, :!⇒:=, :zero?⇒:nonzero?, :nonzero?⇒:zero?, :any?⇒:none?, :none?⇒:any?, :even?⇒:odd?, :odd?⇒:even?}

Style/IpAddresses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.58

0.91

Checks for hardcoded IP addresses, which can make code brittle. IP addresses are likely to need to be changed when code is deployed to a different server or environment, which may break a deployment if forgotten. Prefer setting IP addresses in ENV or other configuration.

Examples

# bad
ip_address = '127.59.241.29'

# good
ip_address = ENV['DEPLOYMENT_IP_ADDRESS']

Configurable attributes

Name Default value Configurable values

AllowedAddresses

::

Array

Exclude

**/*.gemfile, **/Gemfile, **/gems.rb, **/*.gemspec

Array

Style/KeywordArgumentsMerging

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.68

-

When passing an existing hash as keyword arguments, provide additional arguments directly rather than using merge.

Providing arguments directly is more performant, than using merge, and also leads to a shorter and simpler code.

Examples

# bad
some_method(**opts.merge(foo: true))
some_method(**opts.merge(other_opts))

# good
some_method(**opts, foo: true)
some_method(**opts, **other_opts)

Style/KeywordParametersOrder

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.90

1.7

Enforces that optional keyword parameters are placed at the end of the parameters list.

This improves readability, because when looking through the source, it is expected to find required parameters at the beginning of parameters list and optional parameters at the end.

Examples

# bad
def some_method(first: false, second:, third: 10)
  # body omitted
end

# good
def some_method(second:, first: false, third: 10)
  # body omitted
end

# bad
do_something do |first: false, second:, third: 10|
  # body omitted
end

# good
do_something do |second:, first: false, third: 10|
  # body omitted
end

Style/Lambda

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.40

(by default) checks for uses of the lambda literal syntax for single line lambdas, and the method call syntax for multiline lambdas. It is configurable to enforce one of the styles for both single line and multiline lambdas as well.

Examples

EnforcedStyle: line_count_dependent (default)

# bad
f = lambda { |x| x }
f = ->(x) do
      x
    end

# good
f = ->(x) { x }
f = lambda do |x|
      x
    end

EnforcedStyle: lambda

# bad
f = ->(x) { x }
f = ->(x) do
      x
    end

# good
f = lambda { |x| x }
f = lambda do |x|
      x
    end

EnforcedStyle: literal

# bad
f = lambda { |x| x }
f = lambda do |x|
      x
    end

# good
f = ->(x) { x }
f = ->(x) do
      x
    end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

line_count_dependent

line_count_dependent, lambda, literal

Style/LambdaCall

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.13

0.14

Checks for use of the lambda.(args) syntax.

Examples

EnforcedStyle: call (default)

# bad
lambda.(x, y)

# good
lambda.call(x, y)

EnforcedStyle: braces

# bad
lambda.call(x, y)

# good
lambda.(x, y)

Configurable attributes

Name Default value Configurable values

EnforcedStyle

call

call, braces

Style/LineEndConcatenation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.18

0.64

Checks for string literal concatenation at the end of a line.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver is a string, in which case replacing << with \ would result in a syntax error.

For example, this would be a false positive:

array << 'foo' <<
         'bar' <<
         'baz'

Examples

# bad
some_str = 'ala' +
           'bala'

some_str = 'ala' <<
           'bala'

# good
some_str = 'ala' \
           'bala'

Style/MagicCommentFormat

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.35

-

Ensures magic comments are written consistently throughout your code base. Looks for discrepancies in separators (- vs _) and capitalization for both magic comment directives and values.

Required capitalization can be set with the DirectiveCapitalization and ValueCapitalization configuration keys.

If one of these configuration is set to nil, any capitalization is allowed.

Examples

EnforcedStyle: snake_case (default)

# The `snake_case` style will enforce that the frozen string literal
# comment is written in snake case. (Words separated by underscores)
# bad
# frozen-string-literal: true

module Bar
  # ...
end

# good
# frozen_string_literal: false

module Bar
  # ...
end

EnforcedStyle: kebab_case

# The `kebab_case` style will enforce that the frozen string literal
# comment is written in kebab case. (Words separated by hyphens)
# bad
# frozen_string_literal: true

module Baz
  # ...
end

# good
# frozen-string-literal: true

module Baz
  # ...
end

DirectiveCapitalization: lowercase (default)

# bad
# FROZEN-STRING-LITERAL: true

# good
# frozen-string-literal: true

DirectiveCapitalization: uppercase

# bad
# frozen-string-literal: true

# good
# FROZEN-STRING-LITERAL: true

DirectiveCapitalization: nil

# any capitalization is accepted

# good
# frozen-string-literal: true

# good
# FROZEN-STRING-LITERAL: true

ValueCapitalization: nil (default)

# any capitalization is accepted

# good
# frozen-string-literal: true

# good
# frozen-string-literal: TRUE

ValueCapitalization: lowercase

# when a value is not given, any capitalization is accepted

# bad
# frozen-string-literal: TRUE

# good
# frozen-string-literal: TRUE

ValueCapitalization: uppercase

# bad
# frozen-string-literal: true

# good
# frozen-string-literal: TRUE

Configurable attributes

Name Default value Configurable values

EnforcedStyle

snake_case

snake_case, kebab_case

DirectiveCapitalization

lowercase

String

ValueCapitalization

<none>

Style/MapCompactWithConditionalBlock

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.30

-

Prefer select or reject over map { …​ }.compact. This cop also handles filter_map { …​ }, similar to map { …​ }.compact.

Examples

# bad
array.map { |e| some_condition? ? e : next }.compact

# bad
array.filter_map { |e| some_condition? ? e : next }

# bad
array.map do |e|
  if some_condition?
    e
  else
    next
  end
end.compact

# bad
array.map do |e|
  next if some_condition?

  e
end.compact

# bad
array.map do |e|
  e if some_condition?
end.compact

# good
array.select { |e| some_condition? }

# good
array.reject { |e| some_condition? }

Style/MapIntoArray

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.63

1.67

Checks for usages of each with <<, push, or append which can be replaced by map.

If PreferredMethods is configured for map in Style/CollectionMethods, this cop uses the specified method for replacement.

The return value of Enumerable#each is self, whereas the return value of Enumerable#map is an Array. They are not autocorrected when a return value could be used because these types differ.
It only detects when the mapping destination is either: * a local variable initialized as an empty array and referred to only by the pushing operation; * or, if it is the single block argument to a [].tap block. This is because, if not, it’s challenging to statically guarantee that the mapping destination variable remains an empty array:
ret = []
src.each { |e| ret << e * 2 } # `<<` method may mutate `ret`

dest = []
src.each { |e| dest << transform(e, dest) } # `transform` method may mutate `dest`

Safety

This cop is unsafe because not all objects that have an each method also have a map method (e.g. ENV). Additionally, for calls with a block, not all objects that have a map method return an array (e.g. Enumerator::Lazy).

Examples

# bad
dest = []
src.each { |e| dest << e * 2 }
dest

# good
dest = src.map { |e| e * 2 }

# bad
[].tap do |dest|
  src.each { |e| dest << e * 2 }
end

# good
dest = src.map { |e| e * 2 }

# good - contains another operation
dest = []
src.each { |e| dest << e * 2; puts e }
dest

Style/MapToHash

Required Ruby version: 2.6
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.24

-

Looks for uses of map.to_h or collect.to_h that could be written with just to_h in Ruby >= 2.6.

Style/HashTransformKeys and Style/HashTransformValues will also change this pattern if only hash keys or hash values are being transformed.

Safety

This cop is unsafe, as it can produce false positives if the receiver is not an Enumerable.

Examples

# bad
something.map { |v| [v, v * 2] }.to_h

# good
something.to_h { |v| [v, v * 2] }

# bad
{foo: bar}.collect { |k, v| [k.to_s, v.do_something] }.to_h

# good
{foo: bar}.to_h { |k, v| [k.to_s, v.do_something] }

Style/MapToSet

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.42

-

Looks for uses of map.to_set or collect.to_set that could be written with just to_set.

Safety

This cop is unsafe, as it can produce false positives if the receiver is not an Enumerable.

Examples

# bad
something.map { |i| i * 2 }.to_set

# good
something.to_set { |i| i * 2 }

# bad
[1, 2, 3].collect { |i| i.to_s }.to_set

# good
[1, 2, 3].to_set { |i| i.to_s }

Style/MethodCallWithArgsParentheses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.47

1.7

Enforces the presence (default) or absence of parentheses in method calls containing arguments.

In the default style (require_parentheses), macro methods are allowed. Additional methods can be added to the AllowedMethods or AllowedPatterns list. These options are valid only in the default style. Macros can be included by either setting IgnoreMacros to false or adding specific macros to the IncludedMacros list.

Precedence of options is as follows:

  1. AllowedMethods

  2. AllowedPatterns

  3. IncludedMacros

If a method is listed in both IncludedMacros and AllowedMethods, then the latter takes precedence (that is, the method is allowed).

In the alternative style (omit_parentheses), there are three additional options.

  1. AllowParenthesesInChaining is false by default. Setting it to true allows the presence of parentheses in the last call during method chaining.

  2. AllowParenthesesInMultilineCall is false by default. Setting it to true allows the presence of parentheses in multi-line method calls.

  3. AllowParenthesesInCamelCaseMethod is false by default. This allows the presence of parentheses when calling a method whose name begins with a capital letter and which has no arguments. Setting it to true allows the presence of parentheses in such a method call even with arguments.

The style of omit_parentheses allows parentheses in cases where omitting them results in ambiguous or syntactically incorrect code.

Non-exhaustive list of examples:

  • Parentheses are required allowed in method calls with arguments inside literals, logical operators, setting default values in position and keyword arguments, chaining and more.

  • Parentheses are allowed in method calls with arguments inside operators to avoid ambiguity. triple-dot syntax introduced in Ruby 2.7 as omitting them starts an endless range.

  • Parentheses are allowed when forwarding arguments with the triple-dot syntax introduced in Ruby 2.7 as omitting them starts an endless range.

  • Parentheses are required in calls with arguments when inside an endless method definition introduced in Ruby 3.0.

  • Ruby 3.1’s hash omission syntax allows parentheses if the method call is in conditionals and requires parentheses if the call is not the value-returning expression. See https://bugs.ruby-lang.org/issues/18396.

  • Parentheses are required in anonymous arguments, keyword arguments and block passing in Ruby 3.2.

Examples

EnforcedStyle: require_parentheses (default)

# bad
array.delete e

# good
array.delete(e)

# good
# Operators don't need parens
foo == bar

# good
# Setter methods don't need parens
foo.bar = baz

# okay with `puts` listed in `AllowedMethods`
puts 'test'

# okay with `^assert` listed in `AllowedPatterns`
assert_equal 'test', x

EnforcedStyle: omit_parentheses

# bad
array.delete(e)

# good
array.delete e

# bad
action.enforce(strict: true)

# good
action.enforce strict: true

# good
# Parentheses are allowed for code that can be ambiguous without
# them.
action.enforce(condition) || other_condition

# good
# Parentheses are allowed for calls that won't produce valid Ruby
# without them.
yield path, File.basename(path)

# good
# Omitting the parentheses in Ruby 3.1 hash omission syntax can lead
# to ambiguous code. We allow them in conditionals and non-last
# expressions. See https://bugs.ruby-lang.org/issues/18396
if meets(criteria:, action:)
  safe_action(action) || dangerous_action(action)
end

IgnoreMacros: true (default)

# good
class Foo
  bar :baz
end

IgnoreMacros: false

# bad
class Foo
  bar :baz
end

AllowParenthesesInMultilineCall: false (default)

# bad
foo.enforce(
  strict: true
)

# good
foo.enforce \
  strict: true

AllowParenthesesInMultilineCall: true

# good
foo.enforce(
  strict: true
)

# good
foo.enforce \
  strict: true

AllowParenthesesInChaining: false (default)

# bad
foo().bar(1)

# good
foo().bar 1

AllowParenthesesInChaining: true

# good
foo().bar(1)

# good
foo().bar 1

AllowParenthesesInCamelCaseMethod: false (default)

# bad
Array(1)

# good
Array 1

AllowParenthesesInCamelCaseMethod: true

# good
Array(1)

# good
Array 1

AllowParenthesesInStringInterpolation: false (default)

# bad
"#{t('this.is.bad')}"

# good
"#{t 'this.is.better'}"

AllowParenthesesInStringInterpolation: true

# good
"#{t('this.is.good')}"

# good
"#{t 'this.is.also.good'}"

Configurable attributes

Name Default value Configurable values

IgnoreMacros

true

Boolean

AllowedMethods

[]

Array

AllowedPatterns

[]

Array

IncludedMacros

[]

Array

AllowParenthesesInMultilineCall

false

Boolean

AllowParenthesesInChaining

false

Boolean

AllowParenthesesInCamelCaseMethod

false

Boolean

AllowParenthesesInStringInterpolation

false

Boolean

EnforcedStyle

require_parentheses

require_parentheses, omit_parentheses

Style/MethodCallWithoutArgsParentheses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.47

0.55

Checks for unwanted parentheses in parameterless method calls.

This cop’s allowed methods can be customized with AllowedMethods. By default, there are no allowed methods.

This cop allows the use of it() without arguments in blocks, as in 0.times { it() }, following Lint/ItWithoutArgumentsInBlock cop.

Examples

# bad
object.some_method()

# good
object.some_method

AllowedMethods: [] (default)

# bad
object.foo()

AllowedMethods: [foo]

# good
object.foo()

Configurable attributes

Name Default value Configurable values

AllowedMethods

[]

Array

AllowedPatterns

[]

Array

Style/MethodCalledOnDoEndBlock

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.14

-

Checks for methods called on a do…​end block. The point of this check is that it’s easy to miss the call tacked on to the block when reading code.

Examples

# bad
a do
  b
end.c

# good
a { b }.c

# good
foo = a do
  b
end
foo.c

Style/MethodDefParentheses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.16

1.7

Checks for parentheses around the arguments in method definitions. Both instance and class/singleton methods are checked.

Regardless of style, parentheses are necessary for:

  1. Endless methods

  2. Argument lists containing a forward-arg (…​)

  3. Argument lists containing an anonymous rest arguments forwarding (*)

  4. Argument lists containing an anonymous keyword rest arguments forwarding (**)

  5. Argument lists containing an anonymous block forwarding (&)

Removing the parens would be a syntax error here.

Examples

EnforcedStyle: require_parentheses (default)

# The `require_parentheses` style requires method definitions
# to always use parentheses

# bad
def bar num1, num2
  num1 + num2
end

def foo descriptive_var_name,
        another_descriptive_var_name,
        last_descriptive_var_name
  do_something
end

# good
def bar(num1, num2)
  num1 + num2
end

def foo(descriptive_var_name,
        another_descriptive_var_name,
        last_descriptive_var_name)
  do_something
end

EnforcedStyle: require_no_parentheses

# The `require_no_parentheses` style requires method definitions
# to never use parentheses

# bad
def bar(num1, num2)
  num1 + num2
end

def foo(descriptive_var_name,
        another_descriptive_var_name,
        last_descriptive_var_name)
  do_something
end

# good
def bar num1, num2
  num1 + num2
end

def foo descriptive_var_name,
        another_descriptive_var_name,
        last_descriptive_var_name
  do_something
end

EnforcedStyle: require_no_parentheses_except_multiline

# The `require_no_parentheses_except_multiline` style prefers no
# parentheses when method definition arguments fit on single line,
# but prefers parentheses when arguments span multiple lines.

# bad
def bar(num1, num2)
  num1 + num2
end

def foo descriptive_var_name,
        another_descriptive_var_name,
        last_descriptive_var_name
  do_something
end

# good
def bar num1, num2
  num1 + num2
end

def foo(descriptive_var_name,
        another_descriptive_var_name,
        last_descriptive_var_name)
  do_something
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

require_parentheses

require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline

Style/MinMax

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.50

-

Checks for potential uses of Enumerable#minmax.

Examples

# bad
bar = [foo.min, foo.max]
return foo.min, foo.max

# good
bar = foo.minmax
return foo.minmax

Style/MinMaxComparison

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.42

-

Enforces the use of max or min instead of comparison for greater or less.

It can be used if you want to present limit or threshold in Ruby 2.7+. That it is slow though. So autocorrection will apply generic max or min:
a.clamp(b..) # Same as `[a, b].max`
a.clamp(..b) # Same as `[a, b].min`

Safety

This cop is unsafe because even if a value has < or > method, it is not necessarily Comparable.

Examples

# bad
a > b ? a : b
a >= b ? a : b

# good
[a, b].max

# bad
a < b ? a : b
a <= b ? a : b

# good
[a, b].min

Style/MissingElse

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.30

0.38

Checks for if expressions that do not have an else branch.

Pattern matching is allowed to have no else branch because unlike if and case, it raises NoMatchingPatternError if the pattern doesn’t match and without having else.

Supported styles are: if, case, both.

Examples

EnforcedStyle: both (default)

# warn when an `if` or `case` expression is missing an `else` branch.

# bad
if condition
  statement
end

# bad
case var
when condition
  statement
end

# good
if condition
  statement
else
  # the content of `else` branch will be determined by Style/EmptyElse
end

# good
case var
when condition
  statement
else
  # the content of `else` branch will be determined by Style/EmptyElse
end

EnforcedStyle: if

# warn when an `if` expression is missing an `else` branch.

# bad
if condition
  statement
end

# good
if condition
  statement
else
  # the content of `else` branch will be determined by Style/EmptyElse
end

# good
case var
when condition
  statement
end

# good
case var
when condition
  statement
else
  # the content of `else` branch will be determined by Style/EmptyElse
end

EnforcedStyle: case

# warn when a `case` expression is missing an `else` branch.

# bad
case var
when condition
  statement
end

# good
case var
when condition
  statement
else
  # the content of `else` branch will be determined by Style/EmptyElse
end

# good
if condition
  statement
end

# good
if condition
  statement
else
  # the content of `else` branch will be determined by Style/EmptyElse
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

both

if, case, both

Style/MissingRespondToMissing

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.56

-

Checks for the presence of method_missing without also defining respond_to_missing?.

Examples

# bad
def method_missing(name, *args)
  # ...
end

# good
def respond_to_missing?(name, include_private)
  # ...
end

def method_missing(name, *args)
  # ...
end

Style/MixinGrouping

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.48

0.49

Checks for grouping of mixins in class and module bodies. By default it enforces mixins to be placed in separate declarations, but it can be configured to enforce grouping them in one declaration.

Examples

EnforcedStyle: separated (default)

# bad
class Foo
  include Bar, Qox
end

# good
class Foo
  include Qox
  include Bar
end

EnforcedStyle: grouped

# bad
class Foo
  extend Bar
  extend Qox
end

# good
class Foo
  extend Qox, Bar
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

separated

separated, grouped

Style/MixinUsage

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.51

-

Checks that include, extend and prepend statements appear inside classes and modules, not at the top level, so as to not affect the behavior of Object.

Examples

# bad
include M

class C
end

# bad
extend M

class C
end

# bad
prepend M

class C
end

# good
class C
  include M
end

# good
class C
  extend M
end

# good
class C
  prepend M
end

Style/ModuleFunction

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.11

0.65

Checks for use of extend self or module_function in a module.

Supported styles are: module_function (default), extend_self and forbidden.

A couple of things to keep in mind:

  • forbidden style prohibits the usage of both styles

  • in default mode (module_function), the cop won’t be activated when the module contains any private methods

Safety

Autocorrection is unsafe (and is disabled by default) because extend self and module_function do not behave exactly the same.

Examples

EnforcedStyle: module_function (default)

# bad
module Test
  extend self
  # ...
end

# good
module Test
  module_function
  # ...
end

# good
module Test
  extend self
  # ...
  private
  # ...
end

# good
module Test
  class << self
    # ...
  end
end

EnforcedStyle: extend_self

# bad
module Test
  module_function
  # ...
end

# good
module Test
  extend self
  # ...
end

# good
module Test
  class << self
    # ...
  end
end

EnforcedStyle: forbidden

# bad
module Test
  module_function
  # ...
end

# bad
module Test
  extend self
  # ...
end

# bad
module Test
  extend self
  # ...
  private
  # ...
end

# good
module Test
  class << self
    # ...
  end
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

module_function

module_function, extend_self, forbidden

Autocorrect

false

Boolean

Style/MultilineBlockChain

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

No

0.13

-

Checks for chaining of a block after another block that spans multiple lines.

Examples

# bad
Thread.list.select do |t|
  t.alive?
end.map do |t|
  t.object_id
end

# good
alive_threads = Thread.list.select do |t|
  t.alive?
end
alive_threads.map do |t|
  t.object_id
end

Style/MultilineIfModifier

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.45

-

Checks for uses of if/unless modifiers with multiple-lines bodies.

Examples

# bad
{
  result: 'this should not happen'
} unless cond

# good
{ result: 'ok' } if cond

Style/MultilineIfThen

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.26

Checks for uses of the then keyword in multi-line if statements.

Examples

# bad
# This is considered bad practice.
if cond then
end

# good
# If statements can contain `then` on the same line.
if cond then a
elsif cond then b
end

Style/MultilineInPatternThen

Required Ruby version: 2.7
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.16

-

Checks uses of the then keyword in multi-line in statement.

Examples

# bad
case expression
in pattern then
end

# good
case expression
in pattern
end

# good
case expression
in pattern then do_something
end

# good
case expression
in pattern then do_something(arg1,
                             arg2)
end

Style/MultilineMemoization

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.44

0.48

Checks expressions wrapping styles for multiline memoization.

Examples

EnforcedStyle: keyword (default)

# bad
foo ||= (
  bar
  baz
)

# good
foo ||= begin
  bar
  baz
end

EnforcedStyle: braces

# bad
foo ||= begin
  bar
  baz
end

# good
foo ||= (
  bar
  baz
)

Configurable attributes

Name Default value Configurable values

EnforcedStyle

keyword

keyword, braces

Style/MultilineMethodSignature

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.59

1.7

Checks for method signatures that span multiple lines.

Examples

# good

def foo(bar, baz)
end

# bad

def foo(bar,
        baz)
end

Style/MultilineTernaryOperator

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.86

Checks for multi-line ternary op expressions.

return if …​ else …​ end is syntax error. If return is used before multiline ternary operator expression, it will be autocorrected to single-line ternary operator. The same is true for break, next, and method call.

Examples

# bad
a = cond ?
  b : c
a = cond ? b :
    c
a = cond ?
    b :
    c

return cond ?
       b :
       c

# good
a = cond ? b : c
a = if cond
  b
else
  c
end

return cond ? b : c

Style/MultilineWhenThen

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.73

-

Checks uses of the then keyword in multi-line when statements.

Examples

# bad
case foo
when bar then
end

# good
case foo
when bar
end

# good
case foo
when bar then do_something
end

# good
case foo
when bar then do_something(arg1,
                           arg2)
end

Style/MultipleComparison

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.49

1.1

Checks against comparing a variable with multiple items, where Array#include?, Set#include? or a case could be used instead to avoid code repetition. It accepts comparisons of multiple method calls to avoid unnecessary method calls by default. It can be configured by AllowMethodComparison option.

Examples

# bad
a = 'a'
foo if a == 'a' || a == 'b' || a == 'c'

# good
a = 'a'
foo if ['a', 'b', 'c'].include?(a)

VALUES = Set['a', 'b', 'c'].freeze
# elsewhere...
foo if VALUES.include?(a)

case foo
when 'a', 'b', 'c' then foo
# ...
end

# accepted (but consider `case` as above)
foo if a == b.lightweight || a == b.heavyweight

AllowMethodComparison: true (default)

# good
foo if a == b.lightweight || a == b.heavyweight

AllowMethodComparison: false

# bad
foo if a == b.lightweight || a == b.heavyweight

# good
foo if [b.lightweight, b.heavyweight].include?(a)

ComparisonsThreshold: 2 (default)

# bad
foo if a == 'a' || a == 'b'

ComparisonsThreshold: 3

# good
foo if a == 'a' || a == 'b'

Configurable attributes

Name Default value Configurable values

AllowMethodComparison

true

Boolean

ComparisonsThreshold

2

Integer

Style/MutableConstant

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.34

1.8

Checks whether some constant value isn’t a mutable literal (e.g. array or hash).

Strict mode can be used to freeze all constants, rather than just literals. Strict mode is considered an experimental feature. It has not been updated with an exhaustive list of all methods that will produce frozen objects so there is a decent chance of getting some false positives. Luckily, there is no harm in freezing an already frozen object.

From Ruby 3.0, this cop honours the magic comment 'shareable_constant_value'. When this magic comment is set to any acceptable value other than none, it will suppress the offenses raised by this cop. It enforces frozen state.

Regexp and Range literals are frozen objects since Ruby 3.0.
From Ruby 3.0, interpolated strings are not frozen when # frozen-string-literal: true is used, so this cop enforces explicit freezing for such strings.
From Ruby 3.0, this cop allows explicit freezing of constants when the shareable_constant_value directive is used.

Safety

This cop’s autocorrection is unsafe since any mutations on objects that are made frozen will change from being accepted to raising FrozenError, and will need to be manually refactored.

Examples

EnforcedStyle: literals (default)

# bad
CONST = [1, 2, 3]

# good
CONST = [1, 2, 3].freeze

# good
CONST = <<~TESTING.freeze
  This is a heredoc
TESTING

# good
CONST = Something.new

EnforcedStyle: strict

# bad
CONST = Something.new

# bad
CONST = Struct.new do
  def foo
    puts 1
  end
end

# good
CONST = Something.new.freeze

# good
CONST = Struct.new do
  def foo
    puts 1
  end
end.freeze
# Magic comment - shareable_constant_value: literal

# bad
CONST = [1, 2, 3]

# good
# shareable_constant_value: literal
CONST = [1, 2, 3]

Configurable attributes

Name Default value Configurable values

EnforcedStyle

literals

literals, strict

Style/NegatedIf

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.20

0.48

Checks for uses of if with a negated condition. Only ifs without else are considered. There are three different styles:

  • both

  • prefix

  • postfix

Examples

EnforcedStyle: both (default)

# enforces `unless` for `prefix` and `postfix` conditionals

# bad

if !foo
  bar
end

# good

unless foo
  bar
end

# bad

bar if !foo

# good

bar unless foo

EnforcedStyle: prefix

# enforces `unless` for just `prefix` conditionals

# bad

if !foo
  bar
end

# good

unless foo
  bar
end

# good

bar if !foo

EnforcedStyle: postfix

# enforces `unless` for just `postfix` conditionals

# bad

bar if !foo

# good

bar unless foo

# good

if !foo
  bar
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

both

both, prefix, postfix

Style/NegatedIfElseCondition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.2

-

Checks for uses of if-else and ternary operators with a negated condition which can be simplified by inverting condition and swapping branches.

Examples

# bad
if !x
  do_something
else
  do_something_else
end

# good
if x
  do_something_else
else
  do_something
end

# bad
!x ? do_something : do_something_else

# good
x ? do_something_else : do_something

Style/NegatedUnless

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.69

-

Checks for uses of unless with a negated condition. Only unless without else are considered. There are three different styles:

  • both

  • prefix

  • postfix

Examples

EnforcedStyle: both (default)

# enforces `if` for `prefix` and `postfix` conditionals

# bad
unless !foo
  bar
end

# good
if foo
  bar
end

# bad
bar unless !foo

# good
bar if foo

EnforcedStyle: prefix

# enforces `if` for just `prefix` conditionals

# bad
unless !foo
  bar
end

# good
if foo
  bar
end

# good
bar unless !foo

EnforcedStyle: postfix

# enforces `if` for just `postfix` conditionals

# bad
bar unless !foo

# good
bar if foo

# good
unless !foo
  bar
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

both

both, prefix, postfix

Style/NegatedWhile

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.20

-

Checks for uses of while with a negated condition.

Examples

# bad
while !foo
  bar
end

# good
until foo
  bar
end

# bad
bar until !foo

# good
bar while foo
bar while !foo && baz

Style/NestedFileDirname

Required Ruby version: 3.1
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.26

-

Checks for nested File.dirname. It replaces nested File.dirname with the level argument introduced in Ruby 3.1.

Examples

# bad
File.dirname(File.dirname(path))

# good
File.dirname(path, 2)

Style/NestedModifier

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.35

-

Checks for nested use of if, unless, while and until in their modifier form.

Examples

# bad
something if a if b

# good
something if b && a

Style/NestedParenthesizedCalls

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.36

0.77

Checks for unparenthesized method calls in the argument list of a parenthesized method call. be, be_a, be_an, be_between, be_falsey, be_kind_of, be_instance_of, be_truthy, be_within, eq, eql, end_with, include, match, raise_error, respond_to, and start_with methods are allowed by default. These are customizable with AllowedMethods option.

Examples

# good
method1(method2(arg))

# bad
method1(method2 arg)

AllowedMethods: [foo]

# good
method1(foo arg)

Configurable attributes

Name Default value Configurable values

AllowedMethods

be, be_a, be_an, be_between, be_falsey, be_kind_of, be_instance_of, be_truthy, be_within, eq, eql, end_with, include, match, raise_error, respond_to, start_with

Array

Style/NestedTernaryOperator

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.86

Checks for nested ternary op expressions.

Examples

# bad
a ? (b ? b1 : b2) : a2

# good
if a
  b ? b1 : b2
else
  a2
end

Style/Next

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.22

0.35

Use next to skip iteration instead of a condition at the end.

Examples

EnforcedStyle: skip_modifier_ifs (default)

# bad
[1, 2].each do |a|
  if a == 1
    puts a
  end
end

# good
[1, 2].each do |a|
  next unless a == 1
  puts a
end

# good
[1, 2].each do |a|
  puts a if a == 1
end

EnforcedStyle: always

# With `always` all conditions at the end of an iteration needs to be
# replaced by next - with `skip_modifier_ifs` the modifier if like
# this one are ignored: `[1, 2].each { |a| puts a if a == 1 }`

# bad
[1, 2].each do |a|
  puts a if a == 1
end

# bad
[1, 2].each do |a|
  if a == 1
    puts a
  end
end

# good
[1, 2].each do |a|
  next unless a == 1
  puts a
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

skip_modifier_ifs

skip_modifier_ifs, always

MinBodyLength

3

Integer

Style/NilComparison

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.12

0.59

Checks for comparison of something with nil using == and nil?.

Supported styles are: predicate, comparison.

Examples

EnforcedStyle: predicate (default)

# bad
if x == nil
end

# good
if x.nil?
end

EnforcedStyle: comparison

# bad
if x.nil?
end

# good
if x == nil
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

predicate

predicate, comparison

Style/NilLambda

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.3

1.15

Checks for lambdas and procs that always return nil, which can be replaced with an empty lambda or proc instead.

Examples

# bad
-> { nil }

lambda do
  next nil
end

proc { nil }

Proc.new do
  break nil
end

# good
-> {}

lambda do
end

-> (x) { nil if x }

proc {}

Proc.new { nil if x }

Style/NonNilCheck

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.20

0.22

Checks for non-nil checks, which are usually redundant.

With IncludeSemanticChanges set to false by default, this cop does not report offenses for !x.nil? and does no changes that might change behavior. Also IncludeSemanticChanges set to false with EnforcedStyle: comparison of Style/NilComparison cop, this cop does not report offenses for x != nil and does no changes to !x.nil? style.

With IncludeSemanticChanges set to true, this cop reports offenses for !x.nil? and autocorrects that and x != nil to solely x, which is usually OK, but might change behavior.

Examples

# bad
if x != nil
end

# good
if x
end

# Non-nil checks are allowed if they are the final nodes of predicate.
# good
def signed_in?
  !current_user.nil?
end

IncludeSemanticChanges: false (default)

# good
if !x.nil?
end

IncludeSemanticChanges: true

# bad
if !x.nil?
end

Configurable attributes

Name Default value Configurable values

IncludeSemanticChanges

false

Boolean

Style/Not

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.20

Checks for uses of the keyword not instead of !.

Examples

# bad - parentheses are required because of op precedence
x = (not something)

# good
x = !something

Style/NumberedParameters

Required Ruby version: 2.7
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

No

1.22

-

Checks for numbered parameters.

It can either restrict the use of numbered parameters to single-lined blocks, or disallow completely numbered parameters.

Examples

EnforcedStyle: allow_single_line (default)

# bad
collection.each do
  puts _1
end

# good
collection.each { puts _1 }

EnforcedStyle: disallow

# bad
collection.each { puts _1 }

# good
collection.each { |item| puts item }

Configurable attributes

Name Default value Configurable values

EnforcedStyle

allow_single_line

allow_single_line, disallow

Style/NumberedParametersLimit

Required Ruby version: 2.7
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

No

1.22

-

Detects use of an excessive amount of numbered parameters in a single block. Having too many numbered parameters can make code too cryptic and hard to read.

The cop defaults to registering an offense if there is more than 1 numbered parameter but this maximum can be configured by setting Max.

Examples

Max: 1 (default)

# bad
use_multiple_numbered_parameters { _1.call(_2, _3, _4) }

# good
array.each { use_array_element_as_numbered_parameter(_1) }
hash.each { use_only_hash_value_as_numbered_parameter(_2) }

Configurable attributes

Name Default value Configurable values

Max

1

Integer

Style/NumericLiteralPrefix

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.41

-

Checks for octal, hex, binary, and decimal literals using uppercase prefixes and corrects them to lowercase prefix or no prefix (in case of decimals).

Examples

EnforcedOctalStyle: zero_with_o (default)

# bad - missing octal prefix
num = 01234

# bad - uppercase prefix
num = 0O1234
num = 0X12AB
num = 0B10101

# bad - redundant decimal prefix
num = 0D1234
num = 0d1234

# good
num = 0o1234
num = 0x12AB
num = 0b10101
num = 1234

EnforcedOctalStyle: zero_only

# bad
num = 0o1234
num = 0O1234

# good
num = 01234

Configurable attributes

Name Default value Configurable values

EnforcedOctalStyle

zero_with_o

zero_with_o, zero_only

Style/NumericLiterals

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.48

Checks for big numeric literals without _ between groups of digits in them.

Additional allowed patterns can be added by adding regexps to the AllowedPatterns configuration. All regexps are treated as anchored even if the patterns do not contain anchors (so \d{4}_\d{4} will allow 1234_5678 but not 1234_5678_9012).

Even if AllowedPatterns are given, autocorrection will only correct to the standard pattern of an _ every 3 digits.

Examples

# bad
1000000
1_00_000
1_0000

# good
1_000_000
1000

Strict: false (default)

# good
10_000_00 # typical representation of $10,000 in cents

Strict: true

# bad
10_000_00 # typical representation of $10,000 in cents

AllowedNumbers: [3000]

# good
3000 # You can specify allowed numbers. (e.g. port number)

Configurable attributes

Name Default value Configurable values

MinDigits

5

Integer

Strict

false

Boolean

AllowedNumbers

[]

Array

AllowedPatterns

[]

Array

Style/NumericPredicate

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.42

0.59

Checks for usage of comparison operators (==, >, <) to test numbers as zero, positive, or negative. These can be replaced by their respective predicate methods. This cop can also be configured to do the reverse.

This cop’s allowed methods can be customized with AllowedMethods. By default, there are no allowed methods.

This cop disregards #nonzero? as its value is truthy or falsey, but not true and false, and thus not always interchangeable with != 0.

This cop allows comparisons to global variables, since they are often populated with objects which can be compared with integers, but are not themselves Integer polymorphic.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver defines the predicates or can be compared to a number, which may lead to a false positive for non-standard classes.

Examples

EnforcedStyle: predicate (default)

# bad
foo == 0
0 > foo
bar.baz > 0

# good
foo.zero?
foo.negative?
bar.baz.positive?

EnforcedStyle: comparison

# bad
foo.zero?
foo.negative?
bar.baz.positive?

# good
foo == 0
0 > foo
bar.baz > 0

AllowedMethods: [] (default) with EnforcedStyle: predicate

# bad
foo == 0
0 > foo
bar.baz > 0

AllowedMethods: [==] with EnforcedStyle: predicate

# good
foo == 0

# bad
0 > foo
bar.baz > 0

AllowedPatterns: [] (default) with EnforcedStyle: comparison

# bad
foo.zero?
foo.negative?
bar.baz.positive?

AllowedPatterns: ['zero'] with EnforcedStyle: predicate

# good
# bad
foo.zero?

# bad
foo.negative?
bar.baz.positive?

Configurable attributes

Name Default value Configurable values

EnforcedStyle

predicate

predicate, comparison

AllowedMethods

[]

Array

AllowedPatterns

[]

Array

Exclude

spec/**/*

Array

Style/ObjectThen

Required Ruby version: 2.6
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.28

-

Enforces the use of consistent method names Object#yield_self or Object#then.

Examples

EnforcedStyle: then (default)

# bad
obj.yield_self { |x| x.do_something }

# good
obj.then { |x| x.do_something }

EnforcedStyle: yield_self

# bad
obj.then { |x| x.do_something }

# good
obj.yield_self { |x| x.do_something }

Configurable attributes

Name Default value Configurable values

EnforcedStyle

then

then, yield_self

Style/OneLineConditional

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.90

Checks for uses of if/then/else/end constructs on a single line. AlwaysCorrectToMultiline config option can be set to true to auto-convert all offenses to multi-line constructs. When AlwaysCorrectToMultiline is false (default case) the autocorrect will first try converting them to ternary operators.

Examples

# bad
if foo then bar else baz end

# bad
unless foo then baz else bar end

# good
foo ? bar : baz

# good
bar if foo

# good
if foo then bar end

# good
if foo
  bar
else
  baz
end

Configurable attributes

Name Default value Configurable values

AlwaysCorrectToMultiline

false

Boolean

Style/OpenStructUse

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

No

1.23

1.51

Flags uses of OpenStruct, as it is now officially discouraged to be used for performance, version compatibility, and potential security issues.

Safety

Note that this cop may flag false positives; for instance, the following legal use of a hand-rolled OpenStruct type would be considered an offense:

module MyNamespace
  class OpenStruct # not the OpenStruct we're looking for
  end

  def new_struct
    OpenStruct.new # resolves to MyNamespace::OpenStruct
  end
end

Examples

# bad
point = OpenStruct.new(x: 0, y: 1)

# good
Point = Struct.new(:x, :y)
point = Point.new(0, 1)

# also good
point = { x: 0, y: 1 }

# bad
test_double = OpenStruct.new(a: 'b')

# good (assumes test using rspec-mocks)
test_double = double
allow(test_double).to receive(:a).and_return('b')

Style/OperatorMethodCall

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.37

-

Checks for redundant dot before operator method call. The target operator methods are |, ^, &, <⇒, ==, ===, =~, >, >=, <, , <<, >>, +, -, , /, %, *, ~, !, !=, and !~.

Examples

# bad
foo.+ bar
foo.& bar

# good
foo + bar
foo & bar

Style/OptionHash

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.33

0.34

Checks for options hashes and discourages them if the current Ruby version supports keyword arguments.

Examples

# bad
def fry(options = {})
  temperature = options.fetch(:temperature, 300)
  # ...
end

# good
def fry(temperature: 300)
  # ...
end

Configurable attributes

Name Default value Configurable values

SuspiciousParamNames

options, opts, args, params, parameters

Array

Allowlist

[]

Array

Style/OptionalArguments

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

No

0.33

0.83

Checks for optional arguments to methods that do not come at the end of the argument list.

Safety

This cop is unsafe because changing a method signature will implicitly change behavior.

Examples

# bad
def foo(a = 1, b, c)
end

# good
def baz(a, b, c = 1)
end

def foobar(a = 1, b = 2, c = 3)
end

Style/OptionalBooleanParameter

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

No

0.89

-

Checks for places where keyword arguments can be used instead of boolean arguments when defining methods. respond_to_missing? method is allowed by default. These are customizable with AllowedMethods option.

Safety

This cop is unsafe because changing a method signature will implicitly change behavior.

Examples

# bad
def some_method(bar = false)
  puts bar
end

# bad - common hack before keyword args were introduced
def some_method(options = {})
  bar = options.fetch(:bar, false)
  puts bar
end

# good
def some_method(bar: false)
  puts bar
end

AllowedMethods: ['some_method']

# good
def some_method(bar = false)
  puts bar
end

Configurable attributes

Name Default value Configurable values

AllowedMethods

respond_to_missing?

Array

Style/OrAssignment

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.50

-

Checks for potential usage of the ||= operator.

Examples

# bad
name = name ? name : 'Bozhidar'

# bad
name = if name
         name
       else
         'Bozhidar'
       end

# bad
unless name
  name = 'Bozhidar'
end

# bad
name = 'Bozhidar' unless name

# good - set name to 'Bozhidar', only if it's nil or false
name ||= 'Bozhidar'

Style/ParallelAssignment

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.32

-

Checks for simple usages of parallel assignment. This will only complain when the number of variables being assigned matched the number of assigning variables.

Examples

# bad
a, b, c = 1, 2, 3
a, b, c = [1, 2, 3]

# good
one, two = *foo
a, b = foo()
a, b = b, a

a = 1
b = 2
c = 3

Style/ParenthesesAroundCondition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.56

Checks for the presence of superfluous parentheses around the condition of if/unless/while/until.

AllowSafeAssignment option for safe assignment. By safe assignment we mean putting parentheses around an assignment to indicate "I know I’m using an assignment as a condition. It’s not a mistake."

Examples

# bad
x += 1 while (x < 10)
foo unless (bar || baz)

if (x > 10)
elsif (x < 3)
end

# good
x += 1 while x < 10
foo unless bar || baz

if x > 10
elsif x < 3
end

AllowSafeAssignment: true (default)

# good
foo unless (bar = baz)

AllowSafeAssignment: false

# bad
foo unless (bar = baz)

AllowInMultilineConditions: false (default)

# bad
if (x > 10 &&
   y > 10)
end

# good
 if x > 10 &&
    y > 10
 end

AllowInMultilineConditions: true

# good
if (x > 10 &&
   y > 10)
end

Configurable attributes

Name Default value Configurable values

AllowSafeAssignment

true

Boolean

AllowInMultilineConditions

false

Boolean

Style/PercentLiteralDelimiters

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.19

0.48

Enforces the consistent usage of %-literal delimiters.

Specify the 'default' key to set all preferred delimiters at once. You can continue to specify individual preferred delimiters to override the default.

Examples

# Style/PercentLiteralDelimiters:
#   PreferredDelimiters:
#     default: '[]'
#     '%i':    '()'

# good
%w[alpha beta] + %i(gamma delta)

# bad
%W(alpha #{beta})

# bad
%I(alpha beta)

Configurable attributes

Name Default value Configurable values

PreferredDelimiters

{"default"⇒"()", "%i"⇒"[]", "%I"⇒"[]", "%r"⇒"{}", "%w"⇒"[]", "%W"⇒"[]"}

Style/PercentQLiterals

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.25

-

Checks for usage of the %Q() syntax when %q() would do.

Examples

EnforcedStyle: lower_case_q (default)

# The `lower_case_q` style prefers `%q` unless
# interpolation is needed.
# bad
%Q[Mix the foo into the baz.]
%Q(They all said: 'Hooray!')

# good
%q[Mix the foo into the baz]
%q(They all said: 'Hooray!')

EnforcedStyle: upper_case_q

# The `upper_case_q` style requires the sole use of `%Q`.
# bad
%q/Mix the foo into the baz./
%q{They all said: 'Hooray!'}

# good
%Q/Mix the foo into the baz./
%Q{They all said: 'Hooray!'}

Configurable attributes

Name Default value Configurable values

EnforcedStyle

lower_case_q

lower_case_q, upper_case_q

Style/PerlBackrefs

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.13

-

Looks for uses of Perl-style regexp match backreferences and their English versions like $1, $2, $&, &+, $MATCH, $PREMATCH, etc.

Examples

# bad
puts $1

# good
puts Regexp.last_match(1)

Style/PreferredHashMethods

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.41

0.70

Checks for uses of methods Hash#has_key? and Hash#has_value?, and suggests using Hash#key? and Hash#value? instead.

It is configurable to enforce the verbose method names, by using the EnforcedStyle: verbose configuration.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver is a Hash or responds to the replacement methods.

Examples

EnforcedStyle: short (default)

# bad
Hash#has_key?
Hash#has_value?

# good
Hash#key?
Hash#value?

EnforcedStyle: verbose

# bad
Hash#key?
Hash#value?

# good
Hash#has_key?
Hash#has_value?

Configurable attributes

Name Default value Configurable values

EnforcedStyle

short

short, verbose

Style/Proc

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.18

Checks for uses of Proc.new where Kernel#proc would be more appropriate.

Examples

# bad
p = Proc.new { |n| puts n }

# good
p = proc { |n| puts n }

Style/QuotedSymbols

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.16

-

Checks if the quotes used for quoted symbols match the configured defaults. By default uses the same configuration as Style/StringLiterals; if that cop is not enabled, the default EnforcedStyle is single_quotes.

String interpolation is always kept in double quotes.

Lint/SymbolConversion can be used in parallel to ensure that symbols are not quoted that don’t need to be. This cop is for configuring the quoting style to use for symbols that require quotes.

Examples

EnforcedStyle: same_as_string_literals (default) / single_quotes

# bad
:"abc-def"

# good
:'abc-def'
:"#{str}"
:"a\'b"

EnforcedStyle: double_quotes

# bad
:'abc-def'

# good
:"abc-def"
:"#{str}"
:"a\'b"

Configurable attributes

Name Default value Configurable values

EnforcedStyle

same_as_string_literals

same_as_string_literals, single_quotes, double_quotes

Style/RaiseArgs

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.14

1.61

Checks the args passed to fail and raise. For exploded style (default), it recommends passing the exception class and message to raise, rather than construct an instance of the error. It will still allow passing just a message, or the construction of an error with more than one argument.

The exploded style works identically, but with the addition that it will also suggest constructing error objects when the exception is passed multiple arguments.

The exploded style has an AllowedCompactTypes configuration option that takes an Array of exception name Strings.

Safety

This cop is unsafe because raise Foo calls Foo.exception, not Foo.new.

Examples

EnforcedStyle: exploded (default)

# bad
raise StandardError.new('message')

# good
raise StandardError, 'message'
fail 'message'
raise MyCustomError
raise MyCustomError.new(arg1, arg2, arg3)
raise MyKwArgError.new(key1: val1, key2: val2)

# With `AllowedCompactTypes` set to ['MyWrappedError']
raise MyWrappedError.new(obj)
raise MyWrappedError.new(obj), 'message'

EnforcedStyle: compact

# bad
raise StandardError, 'message'
raise RuntimeError, arg1, arg2, arg3

# good
raise StandardError.new('message')
raise MyCustomError
raise MyCustomError.new(arg1, arg2, arg3)
fail 'message'

Configurable attributes

Name Default value Configurable values

EnforcedStyle

exploded

compact, exploded

AllowedCompactTypes

[]

Array

Style/RandomWithOffset

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.52

-

Checks for the use of randomly generated numbers, added/subtracted with integer literals, as well as those with Integer#succ and Integer#pred methods. Prefer using ranges instead, as it clearly states the intentions.

Examples

# bad
rand(6) + 1
1 + rand(6)
rand(6) - 1
1 - rand(6)
rand(6).succ
rand(6).pred
Random.rand(6) + 1
Kernel.rand(6) + 1
rand(0..5) + 1

# good
rand(1..6)
rand(1...7)

Style/RedundantArgument

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.4

1.55

Checks for a redundant argument passed to certain methods.

This cop is limited to methods with single parameter.

Method names and their redundant arguments can be configured like this:

Methods:
  join: ''
  sum: 0
  split: ' '
  chomp: "\n"
  chomp!: "\n"
  foo: 2

Safety

This cop is unsafe because of the following limitations:

  1. This cop matches by method names only and hence cannot tell apart methods with same name in different classes.

  2. This cop may be unsafe if certain special global variables (e.g. $;, $/) are set. That depends on the nature of the target methods, of course. For example, the default argument to join is $OUTPUT_FIELD_SEPARATOR (or $,) rather than '', and if that global is changed, '' is no longer a redundant argument.

Examples

# bad
array.join('')
[1, 2, 3].join("")
array.sum(0)
exit(true)
exit!(false)
string.split(" ")
"first\nsecond".split(" ")
string.chomp("\n")
string.chomp!("\n")
A.foo(2)

# good
array.join
[1, 2, 3].join
array.sum
exit
exit!
string.split
"first second".split
string.chomp
string.chomp!
A.foo

Configurable attributes

Name Default value Configurable values

Methods

{"join"⇒"", "sum"⇒0, "exit"⇒true, "exit!"⇒false, "split"⇒" ", "chomp"⇒"\n", "chomp!"⇒"\n"}

Style/RedundantArrayConstructor

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.52

-

Checks for the instantiation of array using redundant Array constructor. Autocorrect replaces to array literal which is the simplest and fastest.

Examples

# bad
Array.new([])
Array[]
Array([])
Array.new(['foo', 'foo', 'foo'])
Array['foo', 'foo', 'foo']
Array(['foo', 'foo', 'foo'])

# good
[]
['foo', 'foo', 'foo']
Array.new(3, 'foo')
Array.new(3) { 'foo' }

Style/RedundantAssignment

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.87

-

Checks for redundant assignment before returning.

Examples

# bad
def test
  x = foo
  x
end

# bad
def test
  if x
    z = foo
    z
  elsif y
    z = bar
    z
  end
end

# good
def test
  foo
end

# good
def test
  if x
    foo
  elsif y
    bar
  end
end

Style/RedundantBegin

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.10

0.21

Checks for redundant begin blocks.

Currently it checks for code like this:

Examples

# bad
def redundant
  begin
    ala
    bala
  rescue StandardError => e
    something
  end
end

# good
def preferred
  ala
  bala
rescue StandardError => e
  something
end

# bad
begin
  do_something
end

# good
do_something

# bad
# When using Ruby 2.5 or later.
do_something do
  begin
    something
  rescue => ex
    anything
  end
end

# good
# In Ruby 2.5 or later, you can omit `begin` in `do-end` block.
do_something do
  something
rescue => ex
  anything
end

# good
# Stabby lambdas don't support implicit `begin` in `do-end` blocks.
-> do
  begin
    foo
  rescue Bar
    baz
  end
end

Style/RedundantCapitalW

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.76

-

Checks for usage of the %W() syntax when %w() would do.

Examples

# bad
%W(cat dog pig)
%W[door wall floor]

# good
%w/swim run bike/
%w[shirt pants shoes]
%W(apple #{fruit} grape)

Style/RedundantCondition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.76

-

Checks for unnecessary conditional expressions.

Examples

# bad
a = b ? b : c

# good
a = b || c

# bad
if b
  b
else
  c
end

# good
b || c

# good
if b
  b
elsif cond
  c
end

Style/RedundantConditional

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.50

-

Checks for redundant returning of true/false in conditionals.

Examples

# bad
x == y ? true : false

# bad
if x == y
  true
else
  false
end

# good
x == y

# bad
x == y ? false : true

# good
x != y

Style/RedundantConstantBase

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.40

-

Avoid redundant :: prefix on constant.

How Ruby searches constant is a bit complicated, and it can often be difficult to understand from the code whether the :: is intended or not. Where Module.nesting is empty, there is no need to prepend ::, so it would be nice to consistently avoid such meaningless :: prefix to avoid confusion.

This cop is disabled if Lint/ConstantResolution cop is enabled to prevent conflicting rules. Because it respects user configurations that want to enable Lint/ConstantResolution cop which is disabled by default.

Examples

# bad
::Const

# good
Const

# bad
class << self
  ::Const
end

# good
class << self
  Const
end

# good
class A
  ::Const
end

# good
module A
  ::Const
end

Style/RedundantCurrentDirectoryInPath

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.53

-

Checks for uses a redundant current directory in path.

Examples

# bad
require_relative './path/to/feature'

# good
require_relative 'path/to/feature'

Style/RedundantDoubleSplatHashBraces

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.41

-

Checks for redundant uses of double splat hash braces.

Examples

# bad
do_something(**{foo: bar, baz: qux})

# good
do_something(foo: bar, baz: qux)

# bad
do_something(**{foo: bar, baz: qux}.merge(options))

# good
do_something(foo: bar, baz: qux, **options)

Style/RedundantEach

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.38

-

Checks for redundant each.

Safety

This cop is unsafe, as it can produce false positives if the receiver is not an Enumerator.

Examples

# bad
array.each.each { |v| do_something(v) }

# good
array.each { |v| do_something(v) }

# bad
array.each.each_with_index { |v, i| do_something(v, i) }

# good
array.each.with_index { |v, i| do_something(v, i) }
array.each_with_index { |v, i| do_something(v, i) }

# bad
array.each.each_with_object { |v, o| do_something(v, o) }

# good
array.each.with_object { |v, o| do_something(v, o) }
array.each_with_object { |v, o| do_something(v, o) }

Style/RedundantException

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.14

0.29

Checks for RuntimeError as the argument of raise/fail.

Examples

# bad
raise RuntimeError, 'message'
raise RuntimeError.new('message')

# good
raise 'message'

# bad - message is not a string
raise RuntimeError, Object.new
raise RuntimeError.new(Object.new)

# good
raise Object.new.to_s

Style/RedundantFetchBlock

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.86

-

Identifies places where fetch(key) { value } can be replaced by fetch(key, value).

In such cases fetch(key, value) method is faster than fetch(key) { value }.

The block string 'value' in hash.fetch(:key) { 'value' } is detected when frozen string literal magic comment is enabled (i.e. # frozen_string_literal: true), but not when disabled.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver does not have a different implementation of fetch.

Examples

SafeForConstants: false (default)

# bad
hash.fetch(:key) { 5 }
hash.fetch(:key) { true }
hash.fetch(:key) { nil }
array.fetch(5) { :value }
ENV.fetch(:key) { 'value' }

# good
hash.fetch(:key, 5)
hash.fetch(:key, true)
hash.fetch(:key, nil)
array.fetch(5, :value)
ENV.fetch(:key, 'value')

SafeForConstants: true

# bad
ENV.fetch(:key) { VALUE }

# good
ENV.fetch(:key, VALUE)

Configurable attributes

Name Default value Configurable values

SafeForConstants

false

Boolean

Style/RedundantFileExtensionInRequire

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.88

-

Checks for the presence of superfluous .rb extension in the filename provided to require and require_relative.

If the extension is omitted, Ruby tries adding '.rb', '.so', and so on to the name until found. If the file named cannot be found, a LoadError will be raised. There is an edge case where foo.so file is loaded instead of a LoadError if foo.so file exists when require 'foo.rb' will be changed to require 'foo', but that seems harmless.

Examples

# bad
require 'foo.rb'
require_relative '../foo.rb'

# good
require 'foo'
require 'foo.so'
require_relative '../foo'
require_relative '../foo.so'

Style/RedundantFilterChain

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always (Unsafe)

1.52

1.57

Identifies usages of any?, empty? or none? predicate methods chained to select/filter/find_all and change them to use predicate method instead.

Safety

This cop’s autocorrection is unsafe because array.select.any? evaluates all elements through the select method, while array.any? uses short-circuit evaluation. In other words, array.select.any? guarantees the evaluation of every element, but array.any? does not necessarily evaluate all of them.

Examples

# bad
arr.select { |x| x > 1 }.any?

# good
arr.any? { |x| x > 1 }

# bad
arr.select { |x| x > 1 }.empty?
arr.select { |x| x > 1 }.none?

# good
arr.none? { |x| x > 1 }

# good
relation.select(:name).any?
arr.select { |x| x > 1 }.any?(&:odd?)

AllCops:ActiveSupportExtensionsEnabled: false (default)

# good
arr.select { |x| x > 1 }.many?

# good
arr.select { |x| x > 1 }.present?

AllCops:ActiveSupportExtensionsEnabled: true

# bad
arr.select { |x| x > 1 }.many?

# good
arr.many? { |x| x > 1 }

# bad
arr.select { |x| x > 1 }.present?

# good
arr.any? { |x| x > 1 }

Style/RedundantFreeze

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.34

0.66

Check for uses of Object#freeze on immutable objects.

Regexp and Range literals are frozen objects since Ruby 3.0.
From Ruby 3.0, this cop allows explicit freezing of interpolated string literals when # frozen-string-literal: true is used.

Examples

# bad
CONST = 1.freeze

# good
CONST = 1

Style/RedundantHeredocDelimiterQuotes

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.45

-

Checks for redundant heredoc delimiter quotes.

Examples

# bad
do_something(<<~'EOS')
  no string interpolation style text
EOS

# good
do_something(<<~EOS)
  no string interpolation style text
EOS

do_something(<<~'EOS')
  #{string_interpolation_style_text_not_evaluated}
EOS

do_something(<<~'EOS')
  Preserve \
  newlines
EOS

Style/RedundantInitialize

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Command-line only (Unsafe)

1.27

1.61

Checks for initialize methods that are redundant.

An initializer is redundant if it does not do anything, or if it only calls super with the same arguments given to it. If the initializer takes an argument that accepts multiple values (restarg, kwrestarg, etc.) it will not register an offense, because it allows the initializer to take a different number of arguments as its superclass potentially does.

If an initializer argument has a default value, RuboCop assumes it to not be redundant.
Empty initializers are registered as offenses, but it is possible to purposely create an empty initialize method to override a superclass’s initializer.

Safety

This cop is unsafe because if subclass overrides initialize method with a different arity than superclass.

Examples

# bad
def initialize
end

# bad
def initialize
  super
end

# bad
def initialize(a, b)
  super
end

# bad
def initialize(a, b)
  super(a, b)
end

# good
def initialize
  do_something
end

# good
def initialize
  do_something
  super
end

# good (different number of parameters)
def initialize(a, b)
  super(a)
end

# good (default value)
def initialize(a, b = 5)
  super
end

# good (default value)
def initialize(a, b: 5)
  super
end

# good (changes the parameter requirements)
def initialize(*)
end

# good (changes the parameter requirements)
def initialize(**)
end

# good (changes the parameter requirements)
def initialize(...)
end

AllowComments: true (default)

# good
def initialize
  # Overriding to negate superclass `initialize` method.
end

AllowComments: false

# bad
def initialize
  # Overriding to negate superclass `initialize` method.
end

Configurable attributes

Name Default value Configurable values

AllowComments

true

Boolean

Style/RedundantInterpolation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.76

1.30

Checks for strings that are just an interpolated expression.

Safety

Autocorrection is unsafe because when calling a destructive method to string, the resulting string may have different behavior or raise FrozenError.

x = 'a'
y = "#{x}"
y << 'b'   # return 'ab'
x          # return 'a'
y = x.to_s
y << 'b'   # return 'ab'
x          # return 'ab'

x = 'a'.freeze
y = "#{x}"
y << 'b'   # return 'ab'.
y = x.to_s
y << 'b'   # raise `FrozenError`.

Examples

# bad
"#{@var}"

# good
@var.to_s

# good if @var is already a String
@var

Style/RedundantInterpolationUnfreeze

Required Ruby version: 3.0
Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.66

-

Before Ruby 3.0, interpolated strings followed the frozen string literal magic comment which sometimes made it necessary to explicitly unfreeze them. Ruby 3.0 changed interpolated strings to always be unfrozen which makes unfreezing them redundant.

Examples

# bad
+"#{foo} bar"

# bad
"#{foo} bar".dup

# good
"#{foo} bar"

Style/RedundantLineContinuation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.49

-

Check for redundant line continuation.

This cop marks a line continuation as redundant if removing the backslash does not result in a syntax error. However, a backslash at the end of a comment or for string concatenation is not redundant and is not considered an offense.

Examples

# bad
foo. \
  bar
foo \
  &.bar \
    .baz

# good
foo.
  bar
foo
  &.bar
    .baz

# bad
[foo, \
  bar]
{foo: \
  bar}

# good
[foo,
  bar]
{foo:
  bar}

# bad
foo(bar, \
  baz)

# good
foo(bar,
  baz)

# also good - backslash in string concatenation is not redundant
foo('bar' \
  'baz')

# also good - backslash at the end of a comment is not redundant
foo(bar, # \
  baz)

# also good - backslash at the line following the newline begins with a + or -,
# it is not redundant
1 \
  + 2 \
    - 3

# also good - backslash with newline between the method name and its arguments,
# it is not redundant.
some_method \
  (argument)

Style/RedundantParentheses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.36

-

Checks for redundant parentheses.

Examples

# bad
(x) if ((y.z).nil?)

# good
x if y.z.nil?

Style/RedundantPercentQ

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.76

-

Checks for usage of the %q/%Q syntax when '' or "" would do.

Examples

# bad
name = %q(Bruce Wayne)
time = %q(8 o'clock)
question = %q("What did you say?")

# good
name = 'Bruce Wayne'
time = "8 o'clock"
question = '"What did you say?"'

Style/RedundantRegexpArgument

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.53

-

Identifies places where argument can be replaced from a deterministic regexp to a string.

Examples

# bad
'foo'.byteindex(/f/)
'foo'.byterindex(/f/)
'foo'.gsub(/f/, 'x')
'foo'.gsub!(/f/, 'x')
'foo'.partition(/f/)
'foo'.rpartition(/f/)
'foo'.scan(/f/)
'foo'.split(/f/)
'foo'.start_with?(/f/)
'foo'.sub(/f/, 'x')
'foo'.sub!(/f/, 'x')

# good
'foo'.byteindex('f')
'foo'.byterindex('f')
'foo'.gsub('f', 'x')
'foo'.gsub!('f', 'x')
'foo'.partition('f')
'foo'.rpartition('f')
'foo'.scan('f')
'foo'.split('f')
'foo'.start_with?('f')
'foo'.sub('f', 'x')
'foo'.sub!('f', 'x')

Style/RedundantRegexpCharacterClass

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.85

-

Checks for unnecessary single-element Regexp character classes.

Examples

# bad
r = /[x]/

# good
r = /x/

# bad
r = /[\s]/

# good
r = /\s/

# bad
r = %r{/[b]}

# good
r = %r{/b}

# good
r = /[ab]/

Style/RedundantRegexpConstructor

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.52

-

Checks for the instantiation of regexp using redundant Regexp.new or Regexp.compile. Autocorrect replaces to regexp literal which is the simplest and fastest.

Examples

# bad
Regexp.new(/regexp/)
Regexp.compile(/regexp/)

# good
/regexp/
Regexp.new('regexp')
Regexp.compile('regexp')

Style/RedundantRegexpEscape

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.85

-

Checks for redundant escapes inside Regexp literals.

Examples

# bad
%r{foo\/bar}

# good
%r{foo/bar}

# good
/foo\/bar/

# good
%r/foo\/bar/

# good
%r!foo\!bar!

# bad
/a\-b/

# good
/a-b/

# bad
/[\+\-]\d/

# good
/[+\-]\d/

Style/RedundantReturn

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.10

0.14

Checks for redundant return expressions.

Examples

# These bad cases should be extended to handle methods whose body is
# if/else or a case expression with a default branch.

# bad
def test
  return something
end

# bad
def test
  one
  two
  three
  return something
end

# bad
def test
  return something if something_else
end

# good
def test
  something if something_else
end

# good
def test
  if x
  elsif y
  else
  end
end

AllowMultipleReturnValues: false (default)

# bad
def test
  return x, y
end

AllowMultipleReturnValues: true

# good
def test
  return x, y
end

Configurable attributes

Name Default value Configurable values

AllowMultipleReturnValues

false

Boolean

Style/RedundantSelf

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.10

0.13

Checks for redundant uses of self.

The usage of self is only needed when:

  • Sending a message to same object with zero arguments in presence of a method name clash with an argument or a local variable.

  • Calling an attribute writer to prevent a local variable assignment.

Note, with using explicit self you can only send messages with public or protected scope, you cannot send private messages this way.

Note we allow uses of self with operators because it would be awkward otherwise. Also allows the use of self.it without arguments in blocks, as in 0.times { self.it }, following Lint/ItWithoutArgumentsInBlock cop.

Examples

# bad
def foo(bar)
  self.baz
end

# good
def foo(bar)
  self.bar  # Resolves name clash with the argument.
end

def foo
  bar = 1
  self.bar  # Resolves name clash with the local variable.
end

def foo
  %w[x y z].select do |bar|
    self.bar == bar  # Resolves name clash with argument of the block.
  end
end

Style/RedundantSelfAssignment

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.90

-

Checks for places where redundant assignments are made for in place modification methods.

Safety

This cop is unsafe, because it can produce false positives for user defined methods having one of the expected names, but not modifying its receiver in place.

Examples

# bad
args = args.concat(ary)
hash = hash.merge!(other)

# good
args.concat(foo)
args += foo
hash.merge!(other)

# bad
self.foo = foo.concat(ary)

# good
foo.concat(ary)
self.foo += ary

Style/RedundantSelfAssignmentBranch

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.19

-

Checks for places where conditional branch makes redundant self-assignment.

It only detects local variable because it may replace state of instance variable, class variable, and global variable that have state across methods with nil.

Examples

# bad
foo = condition ? bar : foo

# good
foo = bar if condition

# bad
foo = condition ? foo : bar

# good
foo = bar unless condition

Style/RedundantSort

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.76

1.22

Identifies instances of sorting and then taking only the first or last element. The same behavior can be accomplished without a relatively expensive sort by using Enumerable#min instead of sorting and taking the first element and Enumerable#max instead of sorting and taking the last element. Similarly, Enumerable#min_by and Enumerable#max_by can replace Enumerable#sort_by calls after which only the first or last element is used.

Safety

This cop is unsafe, because sort…​last and max may not return the same element in all cases.

In an enumerable where there are multiple elements where a <⇒ b == 0, or where the transformation done by the sort_by block has the same result, sort.last and max (or sort_by.last and max_by) will return different elements. sort.last will return the last element but max will return the first element.

For example:

  class MyString < String; end
  strings = [MyString.new('test'), 'test']
  strings.sort.last.class   #=> String
  strings.max.class         #=> MyString
  words = %w(dog horse mouse)
  words.sort_by { |word| word.length }.last   #=> 'mouse'
  words.max_by { |word| word.length }         #=> 'horse'

Examples

# bad
[2, 1, 3].sort.first
[2, 1, 3].sort[0]
[2, 1, 3].sort.at(0)
[2, 1, 3].sort.slice(0)

# good
[2, 1, 3].min

# bad
[2, 1, 3].sort.last
[2, 1, 3].sort[-1]
[2, 1, 3].sort.at(-1)
[2, 1, 3].sort.slice(-1)

# good
[2, 1, 3].max

# bad
arr.sort_by(&:foo).first
arr.sort_by(&:foo)[0]
arr.sort_by(&:foo).at(0)
arr.sort_by(&:foo).slice(0)

# good
arr.min_by(&:foo)

# bad
arr.sort_by(&:foo).last
arr.sort_by(&:foo)[-1]
arr.sort_by(&:foo).at(-1)
arr.sort_by(&:foo).slice(-1)

# good
arr.max_by(&:foo)

Style/RedundantSortBy

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.36

-

Identifies places where sort_by { …​ } can be replaced by sort.

Examples

# bad
array.sort_by { |x| x }
array.sort_by do |var|
  var
end

# good
array.sort

Style/RedundantStringEscape

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.37

-

Checks for redundant escapes in string literals.

Examples

# bad - no need to escape # without following {/$/@
"\#foo"

# bad - no need to escape single quotes inside double quoted string
"\'foo\'"

# bad - heredocs are also checked for unnecessary escapes
<<~STR
  \#foo \"foo\"
STR

# good
"#foo"

# good
"\#{no_interpolation}"

# good
"'foo'"

# good
"foo\
bar"

# good
<<~STR
  #foo "foo"
STR

Style/RegexpLiteral

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.30

Enforces using // or %r around regular expressions.

The following %r cases using a regexp starts with a blank or = as a method argument allowed to prevent syntax errors.
do_something %r{ regexp} # `do_something / regexp/` is an invalid syntax.
do_something %r{=regexp} # `do_something /=regexp/` is an invalid syntax.

Examples

EnforcedStyle: slashes (default)

# bad
snake_case = %r{^[\dA-Z_]+$}

# bad
regex = %r{
  foo
  (bar)
  (baz)
}x

# good
snake_case = /^[\dA-Z_]+$/

# good
regex = /
  foo
  (bar)
  (baz)
/x

EnforcedStyle: percent_r

# bad
snake_case = /^[\dA-Z_]+$/

# bad
regex = /
  foo
  (bar)
  (baz)
/x

# good
snake_case = %r{^[\dA-Z_]+$}

# good
regex = %r{
  foo
  (bar)
  (baz)
}x

EnforcedStyle: mixed

# bad
snake_case = %r{^[\dA-Z_]+$}

# bad
regex = /
  foo
  (bar)
  (baz)
/x

# good
snake_case = /^[\dA-Z_]+$/

# good
regex = %r{
  foo
  (bar)
  (baz)
}x

AllowInnerSlashes: false (default)

# If `false`, the cop will always recommend using `%r` if one or more
# slashes are found in the regexp string.

# bad
x =~ /home\//

# good
x =~ %r{home/}

AllowInnerSlashes: true

# good
x =~ /home\//

Configurable attributes

Name Default value Configurable values

EnforcedStyle

slashes

slashes, percent_r, mixed

AllowInnerSlashes

false

Boolean

Style/RequireOrder

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always (Unsafe)

1.40

-

Sort require and require_relative in alphabetical order.

Safety

This cop’s autocorrection is unsafe because it will obviously change the execution order.

Examples

# bad
require 'b'
require 'a'

# good
require 'a'
require 'b'

# bad
require_relative 'b'
require_relative 'a'

# good
require_relative 'a'
require_relative 'b'

# good (sorted within each section separated by a blank line)
require 'a'
require 'd'

require 'b'
require 'c'

# good
require 'b'
require_relative 'c'
require 'a'

# bad
require 'a'
require 'c' if foo
require 'b'

# good
require 'a'
require 'b'
require 'c' if foo

# bad
require 'c'
if foo
  require 'd'
  require 'b'
end
require 'a'

# good
require 'c'
if foo
  require 'b'
  require 'd'
end
require 'a'

Style/RescueModifier

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.34

Checks for uses of rescue in its modifier form is added for following reasons:

  • The syntax of modifier form rescue can be misleading because it might lead us to believe that rescue handles the given exception but it actually rescue all exceptions to return the given rescue block. In this case, value returned by handle_error or SomeException.

  • Modifier form rescue would rescue all the exceptions. It would silently skip all exception or errors and handle the error. Example: If NoMethodError is raised, modifier form rescue would handle the exception.

Examples

# bad
some_method rescue handle_error

# bad
some_method rescue SomeException

# good
begin
  some_method
rescue
  handle_error
end

# good
begin
  some_method
rescue SomeException
  handle_error
end

Style/RescueStandardError

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.52

-

Checks for rescuing StandardError. There are two supported styles implicit and explicit. This cop will not register an offense if any error other than StandardError is specified.

Examples

EnforcedStyle: explicit (default)

# `explicit` will enforce using `rescue StandardError`
# instead of `rescue`.

# bad
begin
  foo
rescue
  bar
end

# good
begin
  foo
rescue StandardError
  bar
end

# good
begin
  foo
rescue OtherError
  bar
end

# good
begin
  foo
rescue StandardError, SecurityError
  bar
end

EnforcedStyle: implicit

# `implicit` will enforce using `rescue` instead of
# `rescue StandardError`.

# bad
begin
  foo
rescue StandardError
  bar
end

# good
begin
  foo
rescue
  bar
end

# good
begin
  foo
rescue OtherError
  bar
end

# good
begin
  foo
rescue StandardError, SecurityError
  bar
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

explicit

implicit, explicit

Style/ReturnNil

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.50

-

Enforces consistency between return nil and return.

This cop is disabled by default. Because there seems to be a perceived semantic difference between return and return nil. The former can be seen as just halting evaluation, while the latter might be used when the return value is of specific concern.

Supported styles are return and return_nil.

Examples

EnforcedStyle: return (default)

# bad
def foo(arg)
  return nil if arg
end

# good
def foo(arg)
  return if arg
end

EnforcedStyle: return_nil

# bad
def foo(arg)
  return if arg
end

# good
def foo(arg)
  return nil if arg
end

Configurable attributes

Name Default value Configurable values

EnforcedStyle

return

return, return_nil

Style/ReturnNilInPredicateMethodDefinition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always (Unsafe)

1.53

1.67

Checks for predicate method definitions that return nil. A predicate method should only return a boolean value.

Safety

Autocorrection is marked as unsafe because the change of the return value from nil to false could potentially lead to incompatibility issues.

Examples

# bad
def foo?
  return if condition

  do_something?
end

# bad
def foo?
  return nil if condition

  do_something?
end

# good
def foo?
  return false if condition

  do_something?
end

# bad
def foo?
  if condition
    nil
  else
    true
  end
end

# good
def foo?
  if condition
    false
  else
    true
  end
end

AllowedMethods: ['foo?']

# good
def foo?
  return if condition

  do_something?
end

AllowedPatterns: [/foo/]

# good
def foo?
  return if condition

  do_something?
end

Configurable attributes

Name Default value Configurable values

AllowedMethods

[]

Array

AllowedPatterns

[]

Array

Style/SafeNavigation

Required Ruby version: 2.3
Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.43

1.67

Transforms usages of a method call safeguarded by a non nil check for the variable whose method is being called to safe navigation (&.). If there is a method chain, all of the methods in the chain need to be checked for safety, and all of the methods will need to be changed to use safe navigation.

The default for ConvertCodeThatCanStartToReturnNil is false. When configured to true, this will check for code in the format !foo.nil? && foo.bar. As it is written, the return of this code is limited to false and whatever the return of the method is. If this is converted to safe navigation, foo&.bar can start returning nil as well as what the method returns.

The default for MaxChainLength is 2. We have limited the cop to not register an offense for method chains that exceed this option’s value.

This cop will recognize offenses but not autocorrect code when the right hand side (RHS) of the && statement is an || statement (eg. foo && (foo.bar? || foo.baz?)). It can be corrected manually by removing the foo && and adding &. to each foo on the RHS.

Safety

Autocorrection is unsafe because if a value is false, the resulting code will have different behavior or raise an error.

x = false
x && x.foo  # return false
x&.foo      # raises NoMethodError

Examples

# bad
foo.bar if foo
foo.bar.baz if foo
foo.bar(param1, param2) if foo
foo.bar { |e| e.something } if foo
foo.bar(param) { |e| e.something } if foo

foo.bar if !foo.nil?
foo.bar unless !foo
foo.bar unless foo.nil?

foo && foo.bar
foo && foo.bar.baz
foo && foo.bar(param1, param2)
foo && foo.bar { |e| e.something }
foo && foo.bar(param) { |e| e.something }

foo ? foo.bar : nil
foo.nil? ? nil : foo.bar
!foo.nil? ? foo.bar : nil
!foo ? nil : foo.bar

# good
foo&.bar
foo&.bar&.baz
foo&.bar(param1, param2)
foo&.bar { |e| e.something }
foo&.bar(param) { |e| e.something }
foo && foo.bar.baz.qux # method chain with more than 2 methods
foo && foo.nil? # method that `nil` responds to

# Method calls that do not use `.`
foo && foo < bar
foo < bar if foo

# When checking `foo&.empty?` in a conditional, `foo` being `nil` will actually
# do the opposite of what the author intends.
foo && foo.empty?

# This could start returning `nil` as well as the return of the method
foo.nil? || foo.bar
!foo || foo.bar

# Methods that are used on assignment, arithmetic operation or
# comparison should not be converted to use safe navigation
foo.baz = bar if foo
foo.baz + bar if foo
foo.bar > 2 if foo

Configurable attributes

Name Default value Configurable values

ConvertCodeThatCanStartToReturnNil

false

Boolean

AllowedMethods

present?, blank?, presence, try, try!

Array

MaxChainLength

2

Integer

Style/SafeNavigationChainLength

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

No

1.68

-

Enforces safe navigation chains length to not exceed the configured maximum. The longer the chain is, the harder it becomes to track what on it could be returning nil.

There is a potential interplay with Style/SafeNavigation - if both are enabled and their settings are "incompatible", one of the cops will complain about what the other proposes.

E.g. if Style/SafeNavigation is configured with MaxChainLength: 2 (default) and this cop is configured with Max: 1, then for foo.bar.baz if foo the former will suggest foo&.bar&.baz, which is an offense for the latter.

Examples

Max: 2 (default)

# bad
user&.address&.zip&.upcase

# good
user&.address&.zip
user.address.zip if user

Configurable attributes

Name Default value Configurable values

Max

2

Integer

Style/Sample

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.30

-

Identifies usages of shuffle.first, shuffle.last, and shuffle[] and change them to use sample instead.

Examples

# bad
[1, 2, 3].shuffle.first
[1, 2, 3].shuffle.first(2)
[1, 2, 3].shuffle.last
[2, 1, 3].shuffle.at(0)
[2, 1, 3].shuffle.slice(0)
[1, 2, 3].shuffle[2]
[1, 2, 3].shuffle[0, 2]    # sample(2) will do the same
[1, 2, 3].shuffle[0..2]    # sample(3) will do the same
[1, 2, 3].shuffle(random: Random.new).first

# good
[1, 2, 3].shuffle
[1, 2, 3].sample
[1, 2, 3].sample(3)
[1, 2, 3].shuffle[1, 3]    # sample(3) might return a longer Array
[1, 2, 3].shuffle[1..3]    # sample(3) might return a longer Array
[1, 2, 3].shuffle[foo, bar]
[1, 2, 3].shuffle(random: Random.new)

Style/SelectByRegexp

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always (Unsafe)

1.22

-

Looks for places where an subset of an Enumerable (array, range, set, etc.; see note below) is calculated based on a Regexp match, and suggests grep or grep_v instead.

Hashes do not behave as you may expect with grep, which means that hash.grep is not equivalent to hash.select. Although RuboCop is limited by static analysis, this cop attempts to avoid registering an offense when the receiver is a hash (hash literal, Hash.new, Hash#[], or to_h/to_hash).
grep and grep_v were optimized when used without a block in Ruby 3.0, but may be slower in previous versions. See https://bugs.ruby-lang.org/issues/17030

Safety

Autocorrection is marked as unsafe because MatchData will not be created by grep, but may have previously been relied upon after the match? or =~ call.

Additionally, the cop cannot guarantee that the receiver of select or reject is actually an array by static analysis, so the correction may not be actually equivalent.

Examples

# bad (select, filter, or find_all)
array.select { |x| x.match? /regexp/ }
array.select { |x| /regexp/.match?(x) }
array.select { |x| x =~ /regexp/ }
array.select { |x| /regexp/ =~ x }

# bad (reject)
array.reject { |x| x.match? /regexp/ }
array.reject { |x| /regexp/.match?(x) }
array.reject { |x| x =~ /regexp/ }
array.reject { |x| /regexp/ =~ x }

# good
array.grep(regexp)
array.grep_v(regexp)

Style/SelfAssignment

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.19

0.29

Enforces the use the shorthand for self-assignment.

Examples

# bad
x = x + 1

# good
x += 1

Style/Semicolon

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.19

Checks for multiple expressions placed on the same line. It also checks for lines terminated with a semicolon.

This cop has AllowAsExpressionSeparator configuration option. It allows ; to separate several expressions on the same line.

Examples

# bad
foo = 1; bar = 2;
baz = 3;

# good
foo = 1
bar = 2
baz = 3

AllowAsExpressionSeparator: false (default)

# bad
foo = 1; bar = 2

AllowAsExpressionSeparator: true

# good
foo = 1; bar = 2

Configurable attributes

Name Default value Configurable values

AllowAsExpressionSeparator

false

Boolean

Style/Send

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

0.33

-

Checks for the use of the send method.

Examples

# bad
Foo.send(bar)
quuz.send(fred)

# good
Foo.__send__(bar)
quuz.public_send(fred)

Style/SendWithLiteralMethodName

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.64

-

Detects the use of the public_send method with a literal method name argument. Since the send method can be used to call private methods, by default, only the public_send method is detected.

Writer methods with names ending in = are always permitted because their behavior differs as follows:
def foo=(foo)
  @foo = foo
  42
end

self.foo = 1   # => 1
send(:foo=, 1) # => 42

Safety

This cop is not safe because it can incorrectly detect based on the receiver. Additionally, when AllowSend is set to true, it cannot determine whether the send method being detected is calling a private method.

Examples

# bad
obj.public_send(:method_name)
obj.public_send('method_name')

# good
obj.method_name

AllowSend: true (default)

# good
obj.send(:method_name)
obj.send('method_name')
obj.__send__(:method_name)
obj.__send__('method_name')

AllowSend: false

# bad
obj.send(:method_name)
obj.send('method_name')
obj.__send__(:method_name)
obj.__send__('method_name')

# good
obj.method_name

Configurable attributes

Name Default value Configurable values

AllowSend

true

Boolean

Style/SignalException

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.11

0.37

Checks for uses of fail and raise.

Examples

EnforcedStyle: only_raise (default)

# The `only_raise` style enforces the sole use of `raise`.
# bad
begin
  fail
rescue Exception
  # handle it
end

def watch_out
  fail
rescue Exception
  # handle it
end

Kernel.fail

# good
begin
  raise
rescue Exception
  # handle it
end

def watch_out
  raise
rescue Exception
  # handle it
end

Kernel.raise

EnforcedStyle: only_fail

# The `only_fail` style enforces the sole use of `fail`.
# bad
begin
  raise
rescue Exception
  # handle it
end

def watch_out
  raise
rescue Exception
  # handle it
end

Kernel.raise

# good
begin
  fail
rescue Exception
  # handle it
end

def watch_out
  fail
rescue Exception
  # handle it
end

Kernel.fail

EnforcedStyle: semantic

# The `semantic` style enforces the use of `fail` to signal an
# exception, then will use `raise` to trigger an offense after
# it has been rescued.
# bad
begin
  raise
rescue Exception
  # handle it
end

def watch_out
  # Error thrown
rescue Exception
  fail
end

Kernel.fail
Kernel.raise

# good
begin
  fail
rescue Exception
  # handle it
end

def watch_out
  fail
rescue Exception
  raise 'Preferably with descriptive message'
end

explicit_receiver.fail
explicit_receiver.raise

Configurable attributes

Name Default value Configurable values

EnforcedStyle

only_raise

only_raise, only_fail, semantic

Style/SingleArgumentDig

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.89

-

Sometimes using dig method ends up with just a single argument. In such cases, dig should be replaced with [].

Since replacing hash&.dig(:key) with hash[:key] could potentially lead to error, calls to the dig method using safe navigation will be ignored.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver is an Enumerable or does not have a nonstandard implementation of dig.

Examples

# bad
{ key: 'value' }.dig(:key)
[1, 2, 3].dig(0)

# good
{ key: 'value' }[:key]
[1, 2, 3][0]

# good
{ key1: { key2: 'value' } }.dig(:key1, :key2)
[1, [2, [3]]].dig(1, 1)

# good
keys = %i[key1 key2]
{ key1: { key2: 'value' } }.dig(*keys)

Style/SingleLineBlockParams

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.16

1.6

Checks whether the block parameters of a single-line method accepting a block match the names specified via configuration.

For instance one can configure reduce(inject) to use |a, e| as parameters.

Configuration option: Methods Should be set to use this cop. Array of hashes, where each key is the method name and value - array of argument names.

Examples

Methods: [{reduce: %w[a b]}]

# bad
foo.reduce { |c, d| c + d }
foo.reduce { |_, _d| 1 }

# good
foo.reduce { |a, b| a + b }
foo.reduce { |a, _b| a }
foo.reduce { |a, (id, _)| a + id }
foo.reduce { true }

# good
foo.reduce do |c, d|
  c + d
end

Configurable attributes

Name Default value Configurable values

Methods

{"reduce"⇒["acc", "elem"]}, {"inject"⇒["acc", "elem"]}

Array

Style/SingleLineDoEndBlock

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.57

-

Checks for single-line do…​end block.

In practice a single line do…​end is autocorrected when EnforcedStyle: semantic in Style/BlockDelimiters. The autocorrection maintains the do …​ end syntax to preserve semantics and does not change it to {…​} block.

Examples

# bad
foo do |arg| bar(arg) end

# good
foo do |arg|
  bar(arg)
end

# bad
->(arg) do bar(arg) end

# good
->(arg) { bar(arg) }

Style/SingleLineMethods

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

1.8

Checks for single-line method definitions that contain a body. It will accept single-line methods with no body.

Endless methods added in Ruby 3.0 are also accepted by this cop.

If Style/EndlessMethod is enabled with EnforcedStyle: allow_single_line or allow_always, single-line methods will be autocorrected to endless methods if there is only one statement in the body.

Examples

# bad
def some_method; body end
def link_to(url); {:name => url}; end
def @table.columns; super; end

# good
def self.resource_class=(klass); end
def @table.columns; end
def some_method() = body

AllowIfMethodIsEmpty: true (default)

# good
def no_op; end

AllowIfMethodIsEmpty: false

# bad
def no_op; end

Configurable attributes

Name Default value Configurable values

AllowIfMethodIsEmpty

true

Boolean

Style/SlicingWithRange

Required Ruby version: 2.6
Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.83

-

Checks that arrays are not sliced with the redundant ary[0..-1], replacing it with ary, and ensures arrays are sliced with endless ranges instead of ary[start..-1] on Ruby 2.6+, and with beginless ranges instead of ary[nil..end] on Ruby 2.7+.

Safety

This cop is unsafe because x..-1 and x.. are only guaranteed to be equivalent for Array#[], String#[], and the cop cannot determine what class the receiver is.

For example:

sum = proc { |ary| ary.sum }
sum[-3..-1] # => -6
sum[-3..] # Hangs forever

Examples

# bad
items[0..-1]
items[0..nil]
items[0...nil]

# good
items

# bad
items[1..-1]   # Ruby 2.6+
items[1..nil]  # Ruby 2.6+

# good
items[1..]     # Ruby 2.6+

# bad
items[nil..42] # Ruby 2.7+

# good
items[..42]    # Ruby 2.7+
items[0..42]   # Ruby 2.7+

Style/SoleNestedConditional

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.89

1.5

If the branch of a conditional consists solely of a conditional node, its conditions can be combined with the conditions of the outer branch. This helps to keep the nesting level from getting too deep.

Examples

# bad
if condition_a
  if condition_b
    do_something
  end
end

# bad
if condition_b
  do_something
end if condition_a

# good
if condition_a && condition_b
  do_something
end

AllowModifier: false (default)

# bad
if condition_a
  do_something if condition_b
end

# bad
if condition_b
  do_something
end if condition_a

AllowModifier: true

# good
if condition_a
  do_something if condition_b
end

# good
if condition_b
  do_something
end if condition_a

Configurable attributes

Name Default value Configurable values

AllowModifier

false

Boolean

Style/SpecialGlobalVars

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.13

0.36

Looks for uses of Perl-style global variables. Correcting to global variables in the 'English' library will add a require statement to the top of the file if enabled by RequireEnglish config.

Safety

Autocorrection is marked as unsafe because if RequireEnglish is not true, replacing perl-style variables with english variables will break.

Examples

EnforcedStyle: use_english_names (default)

# good
require 'English' # or this could be in another file.

puts $LOAD_PATH
puts $LOADED_FEATURES
puts $PROGRAM_NAME
puts $ERROR_INFO
puts $ERROR_POSITION
puts $FIELD_SEPARATOR # or $FS
puts $OUTPUT_FIELD_SEPARATOR # or $OFS
puts $INPUT_RECORD_SEPARATOR # or $RS
puts $OUTPUT_RECORD_SEPARATOR # or $ORS
puts $INPUT_LINE_NUMBER # or $NR
puts $LAST_READ_LINE
puts $DEFAULT_OUTPUT
puts $DEFAULT_INPUT
puts $PROCESS_ID # or $PID
puts $CHILD_STATUS
puts $LAST_MATCH_INFO
puts $IGNORECASE
puts $ARGV # or ARGV

EnforcedStyle: use_perl_names

# good
puts $:
puts $"
puts $0
puts $!
puts $@
puts $;
puts $,
puts $/
puts $\
puts $.
puts $_
puts $>
puts $<
puts $$
puts $?
puts $~
puts $=
puts $*

EnforcedStyle: use_builtin_english_names

# good
# Like `use_perl_names` but allows builtin global vars.
puts $LOAD_PATH
puts $LOADED_FEATURES
puts $PROGRAM_NAME
puts ARGV
puts $:
puts $"
puts $0
puts $!
puts $@
puts $;
puts $,
puts $/
puts $\
puts $.
puts $_
puts $>
puts $<
puts $$
puts $?
puts $~
puts $=
puts $*

Configurable attributes

Name Default value Configurable values

RequireEnglish

true

Boolean

EnforcedStyle

use_english_names

use_perl_names, use_english_names, use_builtin_english_names

Style/StabbyLambdaParentheses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.35

-

Check for parentheses around stabby lambda arguments. There are two different styles. Defaults to require_parentheses.

Examples

EnforcedStyle: require_parentheses (default)

# bad
->a,b,c { a + b + c }

# good
->(a,b,c) { a + b + c}

EnforcedStyle: require_no_parentheses

# bad
->(a,b,c) { a + b + c }

# good
->a,b,c { a + b + c}

Configurable attributes

Name Default value Configurable values

EnforcedStyle

require_parentheses

require_parentheses, require_no_parentheses

Style/StaticClass

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

No

Always (Unsafe)

1.3

-

Checks for places where classes with only class methods can be replaced with a module. Classes should be used only when it makes sense to create instances out of them.

Safety

This cop is unsafe, because it is possible that this class is a parent for some other subclass, monkey-patched with instance methods or a dummy instance is instantiated from it somewhere.

Examples

# bad
class SomeClass
  def self.some_method
    # body omitted
  end

  def self.some_other_method
    # body omitted
  end
end

# good
module SomeModule
  module_function

  def some_method
    # body omitted
  end

  def some_other_method
    # body omitted
  end
end

# good - has instance method
class SomeClass
  def instance_method; end
  def self.class_method; end
end

Style/StderrPuts

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.51

-

Identifies places where $stderr.puts can be replaced by warn. The latter has the advantage of easily being disabled by, the -W0 interpreter flag or setting $VERBOSE to nil.

Examples

# bad
$stderr.puts('hello')

# good
warn('hello')

Style/StringChars

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

No

Always (Unsafe)

1.12

-

Checks for uses of String#split with empty string or regexp literal argument.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver is actually a string. If another class has a split method with different behavior, it would be registered as a false positive.

Examples

# bad
string.split(//)
string.split('')

# good
string.chars

Style/StringConcatenation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.89

1.18

Checks for places where string concatenation can be replaced with string interpolation.

The cop can autocorrect simple cases but will skip autocorrecting more complex cases where the resulting code would be harder to read. In those cases, it might be useful to extract statements to local variables or methods which you can then interpolate in a string.

When concatenation between two strings is broken over multiple lines, this cop does not register an offense; instead, Style/LineEndConcatenation will pick up the offense if enabled.

Two modes are supported: 1. aggressive style checks and corrects all occurrences of + where either the left or right side of + is a string literal. 2. conservative style on the other hand, checks and corrects only if left side (receiver of + method call) is a string literal. This is useful when the receiver is some expression that returns string like Pathname instead of a string literal.

Safety

This cop is unsafe in aggressive mode, as it cannot be guaranteed that the receiver is actually a string, which can result in a false positive.

Examples

Mode: aggressive (default)

# bad
email_with_name = user.name + ' <' + user.email + '>'
Pathname.new('/') + 'test'

# good
email_with_name = "#{user.name} <#{user.email}>"
email_with_name = format('%s <%s>', user.name, user.email)
"#{Pathname.new('/')}test"

# accepted, line-end concatenation
name = 'First' +
  'Last'

Mode: conservative

# bad
'Hello' + user.name

# good
"Hello #{user.name}"
user.name + '!!'
Pathname.new('/') + 'test'

Configurable attributes

Name Default value Configurable values

Mode

aggressive

String

Style/StringHashKeys

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

No

Always (Unsafe)

0.52

0.75

Checks for the use of strings as keys in hashes. The use of symbols is preferred instead.

Safety

This cop is unsafe because while symbols are preferred for hash keys, there are instances when string keys are required.

Examples

# bad
{ 'one' => 1, 'two' => 2, 'three' => 3 }

# good
{ one: 1, two: 2, three: 3 }

Style/StringLiterals

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.36

Checks if uses of quotes match the configured preference.

Examples

EnforcedStyle: single_quotes (default)

# bad
"No special symbols"
"No string interpolation"
"Just text"

# good
'No special symbols'
'No string interpolation'
'Just text'
"Wait! What's #{this}!"

EnforcedStyle: double_quotes

# bad
'Just some text'
'No special chars or interpolation'

# good
"Just some text"
"No special chars or interpolation"
"Every string in #{project} uses double_quotes"

Configurable attributes

Name Default value Configurable values

EnforcedStyle

single_quotes

single_quotes, double_quotes

ConsistentQuotesInMultiline

false

Boolean

Style/StringLiteralsInInterpolation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.27

-

Checks that quotes inside string, symbol, and regexp interpolations match the configured preference.

Examples

EnforcedStyle: single_quotes (default)

# bad
string = "Tests #{success ? "PASS" : "FAIL"}"
symbol = :"Tests #{success ? "PASS" : "FAIL"}"
heredoc = <<~TEXT
  Tests #{success ? "PASS" : "FAIL"}
TEXT
regexp = /Tests #{success ? "PASS" : "FAIL"}/

# good
string = "Tests #{success ? 'PASS' : 'FAIL'}"
symbol = :"Tests #{success ? 'PASS' : 'FAIL'}"
heredoc = <<~TEXT
  Tests #{success ? 'PASS' : 'FAIL'}
TEXT
regexp = /Tests #{success ? 'PASS' : 'FAIL'}/

EnforcedStyle: double_quotes

# bad
string = "Tests #{success ? 'PASS' : 'FAIL'}"
symbol = :"Tests #{success ? 'PASS' : 'FAIL'}"
heredoc = <<~TEXT
  Tests #{success ? 'PASS' : 'FAIL'}
TEXT
regexp = /Tests #{success ? 'PASS' : 'FAIL'}/

# good
string = "Tests #{success ? "PASS" : "FAIL"}"
symbol = :"Tests #{success ? "PASS" : "FAIL"}"
heredoc = <<~TEXT
  Tests #{success ? "PASS" : "FAIL"}
TEXT
regexp = /Tests #{success ? "PASS" : "FAIL"}/

Configurable attributes

Name Default value Configurable values

EnforcedStyle

single_quotes

single_quotes, double_quotes

Style/StringMethods

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

Always

0.34

0.34

Enforces the use of consistent method names from the String class.

Examples

# bad
'name'.intern
'var'.unfavored_method

# good
'name'.to_sym
'var'.preferred_method

Configurable attributes

Name Default value Configurable values

PreferredMethods

{"intern"⇒"to_sym"}

Style/Strip

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.36

-

Identifies places where lstrip.rstrip can be replaced by strip.

Examples

# bad
'abc'.lstrip.rstrip
'abc'.rstrip.lstrip

# good
'abc'.strip

Style/StructInheritance

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always (Unsafe)

0.29

1.20

Checks for inheritance from Struct.new.

Safety

Autocorrection is unsafe because it will change the inheritance tree (e.g. return value of Module#ancestors) of the constant.

Examples

# bad
class Person < Struct.new(:first_name, :last_name)
  def age
    42
  end
end

# good
Person = Struct.new(:first_name, :last_name) do
  def age
    42
  end
end

Style/SuperArguments

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.64

-

Checks for redundant argument forwarding when calling super with arguments identical to the method definition.

Using zero arity super within a define_method block results in RuntimeError:

def m
  define_method(:foo) { super() } # => OK
end

def m
  define_method(:foo) { super }   # => RuntimeError
end

Furthermore, any arguments accompanied by a block may potentially be delegating to define_method, therefore, super used within these blocks will be allowed. This approach might result in false negatives, yet ensuring safe detection takes precedence.

Examples

# bad
def method(*args, **kwargs)
  super(*args, **kwargs)
end

# good - implicitly passing all arguments
def method(*args, **kwargs)
  super
end

# good - forwarding a subset of the arguments
def method(*args, **kwargs)
  super(*args)
end

# good - forwarding no arguments
def method(*args, **kwargs)
  super()
end

# good - assigning to the block variable before calling super
def method(&block)
  # Assigning to the block variable would pass the old value to super,
  # under this circumstance the block must be referenced explicitly.
  block ||= proc { 'fallback behavior' }
  super(&block)
end

Style/SuperWithArgsParentheses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.58

-

Enforces the presence of parentheses in super containing arguments.

super is a keyword and is provided as a distinct cop from those designed for method call.

Examples

# bad
super name, age

# good
super(name, age)

Style/SwapValues

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always (Unsafe)

1.1

-

Enforces the use of shorthand-style swapping of 2 variables.

Safety

Autocorrection is unsafe, because the temporary variable used to swap variables will be removed, but may be referred to elsewhere.

Examples

# bad
tmp = x
x = y
y = tmp

# good
x, y = y, x

Style/SymbolArray

Required Ruby version: 2.0
Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.49

Checks for array literals made up of symbols that are not using the %i() syntax.

Alternatively, it checks for symbol arrays using the %i() syntax on projects which do not want to use that syntax, perhaps because they support a version of Ruby lower than 2.0.

Configuration option: MinSize If set, arrays with fewer elements than this value will not trigger the cop. For example, a MinSize of 3 will not enforce a style on an array of 2 or fewer elements.

Examples

EnforcedStyle: percent (default)

# good
%i[foo bar baz]

# bad
[:foo, :bar, :baz]

# bad (contains spaces)
%i[foo\ bar baz\ quux]

# bad (contains [] with spaces)
%i[foo \[ \]]

# bad (contains () with spaces)
%i(foo \( \))

EnforcedStyle: brackets

# good
[:foo, :bar, :baz]

# bad
%i[foo bar baz]

Configurable attributes

Name Default value Configurable values

EnforcedStyle

percent

percent, brackets

MinSize

2

Integer

Style/SymbolLiteral

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.30

-

Checks symbol literal syntax.

Examples

# bad
:"symbol"

# good
:symbol

Style/SymbolProc

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.26

1.64

Use symbols as procs when possible.

If you prefer a style that allows block for method with arguments, please set true to AllowMethodsWithArguments. define_method? methods are allowed by default. These are customizable with AllowedMethods option.

Safety

This cop is unsafe because there is a difference that a Proc generated from Symbol#to_proc behaves as a lambda, while a Proc generated from a block does not. For example, a lambda will raise an ArgumentError if the number of arguments is wrong, but a non-lambda Proc will not.

For example:

class Foo
  def bar
    :bar
  end
end

def call(options = {}, &block)
  block.call(Foo.new, options)
end

call { |x| x.bar }
#=> :bar
call(&:bar)
# ArgumentError: wrong number of arguments (given 1, expected 0)

It is also unsafe because Symbol#to_proc does not work with protected methods which would otherwise be accessible.

For example:

class Box
  def initialize
    @secret = rand
  end

  def normal_matches?(*others)
    others.map { |other| other.secret }.any?(secret)
  end

  def symbol_to_proc_matches?(*others)
    others.map(&:secret).any?(secret)
  end

  protected

  attr_reader :secret
end

boxes = [Box.new, Box.new]
Box.new.normal_matches?(*boxes)
# => false
boxes.first.normal_matches?(*boxes)
# => true
Box.new.symbol_to_proc_matches?(*boxes)
# => NoMethodError: protected method `secret' called for #<Box...>
boxes.first.symbol_to_proc_matches?(*boxes)
# => NoMethodError: protected method `secret' called for #<Box...>

Examples

# bad
something.map { |s| s.upcase }
something.map { _1.upcase }

# good
something.map(&:upcase)

AllowMethodsWithArguments: false (default)

# bad
something.do_something(foo) { |o| o.bar }

# good
something.do_something(foo, &:bar)

AllowMethodsWithArguments: true

# good
something.do_something(foo) { |o| o.bar }

AllowComments: false (default)

# bad
something.do_something do |s| # some comment
  # some comment
  s.upcase # some comment
  # some comment
end

AllowComments: true

# good  - if there are comment in either position
something.do_something do |s| # some comment
  # some comment
  s.upcase # some comment
  # some comment
end

AllowedMethods: [define_method] (default)

# good
define_method(:foo) { |foo| foo.bar }

AllowedPatterns: [] (default)

# bad
something.map { |s| s.upcase }

AllowedPatterns: ['map'] (default)

# good
something.map { |s| s.upcase }

AllCops:ActiveSupportExtensionsEnabled: false (default)

# bad
->(x) { x.foo }
proc { |x| x.foo }
Proc.new { |x| x.foo }

# good
lambda(&:foo)
proc(&:foo)
Proc.new(&:foo)

AllCops:ActiveSupportExtensionsEnabled: true

# good
->(x) { x.foo }
proc { |x| x.foo }
Proc.new { |x| x.foo }

Configurable attributes

Name Default value Configurable values

AllowMethodsWithArguments

false

Boolean

AllowedMethods

define_method

Array

AllowedPatterns

[]

Array

AllowComments

false

Boolean

Style/TernaryParentheses

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.42

0.46

Checks for the presence of parentheses around ternary conditions. It is configurable to enforce inclusion or omission of parentheses using EnforcedStyle. Omission is only enforced when removing the parentheses won’t cause a different behavior.

AllowSafeAssignment option for safe assignment. By safe assignment we mean putting parentheses around an assignment to indicate "I know I’m using an assignment as a condition. It’s not a mistake."

Examples

EnforcedStyle: require_no_parentheses (default)

# bad
foo = (bar?) ? a : b
foo = (bar.baz?) ? a : b
foo = (bar && baz) ? a : b

# good
foo = bar? ? a : b
foo = bar.baz? ? a : b
foo = bar && baz ? a : b

EnforcedStyle: require_parentheses

# bad
foo = bar? ? a : b
foo = bar.baz? ? a : b
foo = bar && baz ? a : b

# good
foo = (bar?) ? a : b
foo = (bar.baz?) ? a : b
foo = (bar && baz) ? a : b

EnforcedStyle: require_parentheses_when_complex

# bad
foo = (bar?) ? a : b
foo = (bar.baz?) ? a : b
foo = bar && baz ? a : b

# good
foo = bar? ? a : b
foo = bar.baz? ? a : b
foo = (bar && baz) ? a : b

AllowSafeAssignment: true (default)

# good
foo = (bar = baz) ? a : b

AllowSafeAssignment: false

# bad
foo = (bar = baz) ? a : b

Configurable attributes

Name Default value Configurable values

EnforcedStyle

require_no_parentheses

require_parentheses, require_no_parentheses, require_parentheses_when_complex

AllowSafeAssignment

true

Boolean

Style/TopLevelMethodDefinition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

1.15

-

Newcomers to ruby applications may write top-level methods, when ideally they should be organized in appropriate classes or modules. This cop looks for definitions of top-level methods and warns about them.

However for ruby scripts it is perfectly fine to use top-level methods. Hence this cop is disabled by default.

Examples

# bad
def some_method
end

# bad
def self.some_method
end

# bad
define_method(:foo) { puts 1 }

# good
module Foo
  def some_method
  end
end

# good
class Foo
  def self.some_method
  end
end

# good
Struct.new do
  def some_method
  end
end

# good
class Foo
  define_method(:foo) { puts 1 }
end

Style/TrailingBodyOnClass

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.53

-

Checks for trailing code after the class definition.

Examples

# bad
class Foo; def foo; end
end

# good
class Foo
  def foo; end
end

Style/TrailingBodyOnMethodDefinition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.52

-

Checks for trailing code after the method definition.

It always accepts endless method definitions that are basically on the same line.

Examples

# bad
def some_method; do_stuff
end

def f(x); b = foo
  b[c: x]
end

# good
def some_method
  do_stuff
end

def f(x)
  b = foo
  b[c: x]
end

def endless_method = do_stuff

Style/TrailingBodyOnModule

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.53

-

Checks for trailing code after the module definition.

Examples

# bad
module Foo extend self
end

# good
module Foo
  extend self
end

Style/TrailingCommaInArguments

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.36

-

Checks for trailing comma in argument lists. The supported styles are:

  • consistent_comma: Requires a comma after the last argument, for all parenthesized method calls with arguments.

  • comma: Requires a comma after the last argument, but only for parenthesized method calls where each argument is on its own line.

  • no_comma: Requires that there is no comma after the last argument.

Examples

EnforcedStyleForMultiline: consistent_comma

# bad
method(1, 2,)

# good
method(1, 2)

# good
method(
  1, 2,
  3,
)

# good
method(
  1, 2, 3,
)

# good
method(
  1,
  2,
)

EnforcedStyleForMultiline: comma

# bad
method(1, 2,)

# good
method(1, 2)

# bad
method(
  1, 2,
  3,
)

# good
method(
  1, 2,
  3
)

# bad
method(
  1, 2, 3,
)

# good
method(
  1, 2, 3
)

# good
method(
  1,
  2,
)

EnforcedStyleForMultiline: no_comma (default)

# bad
method(1, 2,)

# good
method(1, 2)

# good
method(
  1,
  2
)

Configurable attributes

Name Default value Configurable values

EnforcedStyleForMultiline

no_comma

comma, consistent_comma, no_comma

Style/TrailingCommaInArrayLiteral

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.53

-

Checks for trailing comma in array literals. The configuration options are:

  • consistent_comma: Requires a comma after the last item of all non-empty, multiline array literals.

  • comma: Requires a comma after last item in an array, but only when each item is on its own line.

  • no_comma: Does not require a comma after the last item in an array

Examples

EnforcedStyleForMultiline: consistent_comma

# bad
a = [1, 2,]

# good
a = [1, 2]

# good
a = [
  1, 2,
  3,
]

# good
a = [
  1, 2, 3,
]

# good
a = [
  1,
  2,
]

EnforcedStyleForMultiline: comma

# bad
a = [1, 2,]

# good
a = [1, 2]

# bad
a = [
  1, 2,
  3,
]

# good
a = [
  1, 2,
  3
]

# bad
a = [
  1, 2, 3,
]

# good
a = [
  1, 2, 3
]

# good
a = [
  1,
  2,
]

EnforcedStyleForMultiline: no_comma (default)

# bad
a = [1, 2,]

# good
a = [
  1,
  2
]

Configurable attributes

Name Default value Configurable values

EnforcedStyleForMultiline

no_comma

comma, consistent_comma, no_comma

Style/TrailingCommaInBlockArgs

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

No

Always (Unsafe)

0.81

-

Checks whether trailing commas in block arguments are required. Blocks with only one argument and a trailing comma require that comma to be present. Blocks with more than one argument never require a trailing comma.

Safety

This cop is unsafe because a trailing comma can indicate there are more parameters that are not used.

For example:

# with a trailing comma
{foo: 1, bar: 2, baz: 3}.map {|key,| key }
#=> [:foo, :bar, :baz]

# without a trailing comma
{foo: 1, bar: 2, baz: 3}.map {|key| key }
#=> [[:foo, 1], [:bar, 2], [:baz, 3]]

This can be fixed by replacing the trailing comma with a placeholder argument (such as |key, _value|).

Examples

# bad
add { |foo, bar,| foo + bar }

# good
add { |foo, bar| foo + bar }

# good
add { |foo,| foo }

# good
add { foo }

# bad
add do |foo, bar,|
  foo + bar
end

# good
add do |foo, bar|
  foo + bar
end

# good
add do |foo,|
  foo
end

# good
add do
  foo + bar
end

Style/TrailingCommaInHashLiteral

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.53

-

Checks for trailing comma in hash literals. The configuration options are:

  • consistent_comma: Requires a comma after the last item of all non-empty, multiline hash literals.

  • comma: Requires a comma after the last item in a hash, but only when each item is on its own line.

  • no_comma: Does not require a comma after the last item in a hash

Examples

EnforcedStyleForMultiline: consistent_comma

# bad
a = { foo: 1, bar: 2, }

# good
a = { foo: 1, bar: 2 }

# good
a = {
  foo: 1, bar: 2,
  qux: 3,
}

# good
a = {
  foo: 1, bar: 2, qux: 3,
}

# good
a = {
  foo: 1,
  bar: 2,
}

EnforcedStyleForMultiline: comma

# bad
a = { foo: 1, bar: 2, }

# good
a = { foo: 1, bar: 2 }

# bad
a = {
  foo: 1, bar: 2,
  qux: 3,
}

# good
a = {
  foo: 1, bar: 2,
  qux: 3
}

# bad
a = {
  foo: 1, bar: 2, qux: 3,
}

# good
a = {
  foo: 1, bar: 2, qux: 3
}

# good
a = {
  foo: 1,
  bar: 2,
}

EnforcedStyleForMultiline: no_comma (default)

# bad
a = { foo: 1, bar: 2, }

# good
a = {
  foo: 1,
  bar: 2
}

Configurable attributes

Name Default value Configurable values

EnforcedStyleForMultiline

no_comma

comma, consistent_comma, no_comma

Style/TrailingMethodEndStatement

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.52

-

Checks for trailing code after the method definition.

Examples

# bad
def some_method
do_stuff; end

def do_this(x)
  baz.map { |b| b.this(x) } end

def foo
  block do
    bar
  end end

# good
def some_method
  do_stuff
end

def do_this(x)
  baz.map { |b| b.this(x) }
end

def foo
  block do
    bar
  end
end

Style/TrailingUnderscoreVariable

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.31

0.35

Checks for extra underscores in variable assignment.

Examples

# bad
a, b, _ = foo()
a, b, _, = foo()
a, _, _ = foo()
a, _, _, = foo()

# good
a, b, = foo()
a, = foo()
*a, b, _ = foo()
# => We need to know to not include 2 variables in a
a, *b, _ = foo()
# => The correction `a, *b, = foo()` is a syntax error

AllowNamedUnderscoreVariables: true (default)

# good
a, b, _something = foo()

AllowNamedUnderscoreVariables: false

# bad
a, b, _something = foo()

Configurable attributes

Name Default value Configurable values

AllowNamedUnderscoreVariables

true

Boolean

Style/TrivialAccessors

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

1.15

Looks for trivial reader/writer methods, that could have been created with the attr_* family of functions automatically. to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, and to_sym methods are allowed by default. These are customizable with AllowedMethods option.

Examples

# bad
def foo
  @foo
end

def bar=(val)
  @bar = val
end

def self.baz
  @baz
end

# good
attr_reader :foo
attr_writer :bar

class << self
  attr_reader :baz
end

ExactNameMatch: true (default)

# good
def name
  @other_name
end

ExactNameMatch: false

# bad
def name
  @other_name
end

AllowPredicates: true (default)

# good
def foo?
  @foo
end

AllowPredicates: false

# bad
def foo?
  @foo
end

# good
attr_reader :foo

AllowDSLWriters: true (default)

# good
def on_exception(action)
  @on_exception=action
end

AllowDSLWriters: false

# bad
def on_exception(action)
  @on_exception=action
end

# good
attr_writer :on_exception

IgnoreClassMethods: false (default)

# bad
def self.foo
  @foo
end

# good
class << self
  attr_reader :foo
end

IgnoreClassMethods: true

# good
def self.foo
  @foo
end

AllowedMethods: ['allowed_method']

# good
def allowed_method
  @foo
end

Configurable attributes

Name Default value Configurable values

ExactNameMatch

true

Boolean

AllowPredicates

true

Boolean

AllowDSLWriters

true

Boolean

IgnoreClassMethods

false

Boolean

AllowedMethods

to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym

Array

Style/UnlessElse

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

-

Looks for unless expressions with else clauses.

Examples

# bad
unless foo_bar.nil?
  # do something...
else
  # do a different thing...
end

# good
if foo_bar.present?
  # do something...
else
  # do a different thing...
end

Style/UnlessLogicalOperators

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

Yes

No

1.11

-

Checks for the use of logical operators in an unless condition. It discourages such code, as the condition becomes more difficult to read and understand.

This cop supports two styles:

  • forbid_mixed_logical_operators (default)

  • forbid_logical_operators

forbid_mixed_logical_operators style forbids the use of more than one type of logical operators. This makes the unless condition easier to read because either all conditions need to be met or any condition need to be met in order for the expression to be truthy or falsey.

forbid_logical_operators style forbids any use of logical operator. This makes it even more easy to read the unless condition as there is only one condition in the expression.

Examples

EnforcedStyle: forbid_mixed_logical_operators (default)

# bad
return unless a || b && c
return unless a && b || c
return unless a && b and c
return unless a || b or c
return unless a && b or c
return unless a || b and c

# good
return unless a && b && c
return unless a || b || c
return unless a and b and c
return unless a or b or c
return unless a?

EnforcedStyle: forbid_logical_operators

# bad
return unless a || b
return unless a && b
return unless a or b
return unless a and b

# good
return unless a
return unless a?

Configurable attributes

Name Default value Configurable values

EnforcedStyle

forbid_mixed_logical_operators

forbid_mixed_logical_operators, forbid_logical_operators

Style/UnpackFirst

Required Ruby version: 2.4
Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.54

-

Checks for accessing the first element of String#unpack which can be replaced with the shorter method unpack1.

Examples

# bad
'foo'.unpack('h*').first
'foo'.unpack('h*')[0]
'foo'.unpack('h*').slice(0)
'foo'.unpack('h*').at(0)

# good
'foo'.unpack1('h*')

Style/VariableInterpolation

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.20

Checks for variable interpolation (like "#@ivar").

Examples

# bad
"His name is #$name"
/check #$pattern/
"Let's go to the #@store"

# good
"His name is #{$name}"
/check #{$pattern}/
"Let's go to the #{@store}"

Style/WhenThen

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

-

Checks for when; uses in case expressions.

Examples

# bad
case foo
when 1; 'baz'
when 2; 'bar'
end

# good
case foo
when 1 then 'baz'
when 2 then 'bar'
end

Style/WhileUntilDo

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

-

Checks for uses of do in multi-line while/until statements.

Examples

# bad
while x.any? do
  do_something(x.pop)
end

# good
while x.any?
  do_something(x.pop)
end

# bad
until x.empty? do
  do_something(x.pop)
end

# good
until x.empty?
  do_something(x.pop)
end

Style/WhileUntilModifier

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

0.30

Checks for while and until statements that would fit on one line if written as a modifier while/until. The maximum line length is configured in the Layout/LineLength cop.

Examples

# bad
while x < 10
  x += 1
end

# good
x += 1 while x < 10

# bad
until x > 10
  x += 1
end

# good
x += 1 until x > 10
# bad
x += 100 while x < 500 # a long comment that makes code too long if it were a single line

# good
while x < 500 # a long comment that makes code too long if it were a single line
  x += 100
end

Style/WordArray

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

Yes

Always

0.9

1.19

Checks for array literals made up of word-like strings, that are not using the %w() syntax.

Alternatively, it can check for uses of the %w() syntax, in projects which do not want to include that syntax.

When using the percent style, %w() arrays containing a space will be registered as offenses.

Configuration option: MinSize If set, arrays with fewer elements than this value will not trigger the cop. For example, a MinSize of 3 will not enforce a style on an array of 2 or fewer elements.

Examples

EnforcedStyle: percent (default)

# good
%w[foo bar baz]

# bad
['foo', 'bar', 'baz']

# bad (contains spaces)
%w[foo\ bar baz\ quux]

# bad
[
  ['one', 'One'],
  ['two', 'Two']
]

# good
[
  %w[one One],
  %w[two Two]
]

# good (2d array containing spaces)
[
  ['one', 'One'],
  ['two', 'Two'],
  ['forty two', 'Forty Two']
]

EnforcedStyle: brackets

# good
['foo', 'bar', 'baz']

# bad
%w[foo bar baz]

# good (contains spaces)
['foo bar', 'baz quux']

# good
[
  ['one', 'One'],
  ['two', 'Two']
]

# bad
[
  %w[one One],
  %w[two Two]
]

Configurable attributes

Name Default value Configurable values

EnforcedStyle

percent

percent, brackets

MinSize

2

Integer

WordRegex

(?-mix:\A(?:\p{Word}|\p{Word}-\p{Word}|\n|\t)+\z)

Style/YAMLFileRead

Enabled by default Safe Supports autocorrection Version Added Version Changed

Pending

Yes

Always

1.53

-

Checks for the use of YAML.load, YAML.safe_load, and YAML.parse with File.read argument.

YAML.safe_load_file was introduced in Ruby 3.0.

Examples

# bad
YAML.load(File.read(path))
YAML.parse(File.read(path))

# good
YAML.load_file(path)
YAML.parse_file(path)

# bad
YAML.safe_load(File.read(path)) # Ruby 3.0 and newer

# good
YAML.safe_load_file(path)       # Ruby 3.0 and newer

Style/YodaCondition

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.49

0.75

Enforces or forbids Yoda conditions, i.e. comparison operations where the order of expression is reversed. eg. 5 == x

Safety

This cop is unsafe because comparison operators can be defined differently on different classes, and are not guaranteed to have the same result if reversed.

For example:

class MyKlass
  def ==(other)
    true
  end
end

obj = MyKlass.new
obj == 'string'   #=> true
'string' == obj   #=> false

Examples

EnforcedStyle: forbid_for_all_comparison_operators (default)

# bad
99 == foo
"bar" != foo
42 >= foo
10 < bar
99 == CONST

# good
foo == 99
foo == "bar"
foo <= 42
bar > 10
CONST == 99
"#{interpolation}" == foo
/#{interpolation}/ == foo

EnforcedStyle: forbid_for_equality_operators_only

# bad
99 == foo
"bar" != foo

# good
99 >= foo
3 < a && a < 5

EnforcedStyle: require_for_all_comparison_operators

# bad
foo == 99
foo == "bar"
foo <= 42
bar > 10

# good
99 == foo
"bar" != foo
42 >= foo
10 < bar

EnforcedStyle: require_for_equality_operators_only

# bad
99 >= foo
3 < a && a < 5

# good
99 == foo
"bar" != foo

Configurable attributes

Name Default value Configurable values

EnforcedStyle

forbid_for_all_comparison_operators

forbid_for_all_comparison_operators, forbid_for_equality_operators_only, require_for_all_comparison_operators, require_for_equality_operators_only

Style/YodaExpression

Enabled by default Safe Supports autocorrection Version Added Version Changed

Disabled

No

Always (Unsafe)

1.42

1.43

Forbids Yoda expressions, i.e. binary operations (using *, +, &, |, and ^ operators) where the order of expression is reversed, eg. 1 + x. This cop complements Style/YodaCondition cop, which has a similar purpose.

This cop is disabled by default to respect user intentions such as:

config.server_port = 9000 + ENV["TEST_ENV_NUMBER"].to_i

Safety

This cop is unsafe because binary operators can be defined differently on different classes, and are not guaranteed to have the same result if reversed.

Examples

SupportedOperators: ['*', '+', '&', '|', '^'] (default)

# bad
10 * y
1 + x
1 & z
1 | x
1 ^ x
1 + CONST

# good
y * 10
x + 1
z & 1
x | 1
x ^ 1
CONST + 1
60 * 24

Configurable attributes

Name Default value Configurable values

Style/ZeroLengthPredicate

Enabled by default Safe Supports autocorrection Version Added Version Changed

Enabled

No

Always (Unsafe)

0.37

0.39

Checks for numeric comparisons that can be replaced by a predicate method, such as receiver.length == 0, receiver.length > 0, and receiver.length != 0, receiver.length < 1 and receiver.size == 0 that can be replaced by receiver.empty? and !receiver.empty?.

File, Tempfile, and StringIO do not have empty? so allow size == 0 and size.zero?.

Safety

This cop is unsafe because it cannot be guaranteed that the receiver has an empty? method that is defined in terms of length. If there is a non-standard class that redefines length or empty?, the cop may register a false positive.

Examples

# bad
[1, 2, 3].length == 0
0 == "foobar".length
array.length < 1
{a: 1, b: 2}.length != 0
string.length > 0
hash.size > 0

# good
[1, 2, 3].empty?
"foobar".empty?
array.empty?
!{a: 1, b: 2}.empty?
!string.empty?
!hash.empty?