Lint

Lint/AmbiguousAssignment

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Pending

Yes

No

1.7

-

This cop checks for mistyped shorthand assignments.

Examples

# bad
x =- y
x =+ y
x =* y
x =! y

# good
x -= y # or x = -y
x += y # or x = +y
x *= y # or x = *y
x != y # or x = !y

Lint/AmbiguousBlockAssociation

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

0.48

-

This cop checks for ambiguous block association with method when param passed without parentheses.

Examples

# bad
some_method a { |val| puts val }
# good
# With parentheses, there's no ambiguity.
some_method(a { |val| puts val })
# or (different meaning)
some_method(a) { |val| puts val }

# good
# Operator methods require no disambiguation
foo == bar { |b| b.baz }

# good
# Lambda arguments require no disambiguation
foo = ->(bar) { bar.baz }

Lint/AmbiguousOperator

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

0.17

0.83

This cop checks for ambiguous operators in the first argument of a method invocation without parentheses.

Examples

# bad

# The `*` is interpreted as a splat operator but it could possibly be
# a `*` method invocation (i.e. `do_something.*(some_array)`).
do_something *some_array
# good

# With parentheses, there's no ambiguity.
do_something(*some_array)

Lint/AmbiguousRegexpLiteral

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

0.17

0.83

This cop checks for ambiguous regexp literals in the first argument of a method invocation without parentheses.

Examples

# bad

# This is interpreted as a method invocation with a regexp literal,
# but it could possibly be `/` method invocations.
# (i.e. `do_something./(pattern)./(i)`)
do_something /pattern/i
# good

# With parentheses, there's no ambiguity.
do_something(/pattern/i)

Lint/AssignmentInCondition

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

0.9

-

This cop checks for assignments in the conditions of if/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
if some_var = true
  do_something
end

# good
if some_var == true
  do_something
end

AllowSafeAssignment: true (default)

# good
if (some_var = true)
  do_something
end

AllowSafeAssignment: false

# bad
if (some_var = true)
  do_something
end

Configurable attributes

Name Default value Configurable values

AllowSafeAssignment

true

Boolean

Lint/BigDecimalNew

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

Yes

0.53

-

BigDecimal.new() is deprecated since BigDecimal 1.3.3. This cop identifies places where BigDecimal.new() can be replaced by BigDecimal().

Examples

# bad
BigDecimal.new(123.456, 3)

# good
BigDecimal(123.456, 3)

Lint/BinaryOperatorWithIdenticalOperands

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

No

No

0.89

1.7

This cop checks for places where binary operator has identical operands.

It covers arithmetic operators: +, -, , /, %, *; comparison operators: ==, ===, =~, >, >=, <, ; bitwise operators: |, ^, &, <<, >>; boolean operators: &&, || and "spaceship" operator - <⇒.

This cop is marked as unsafe as it does not consider side effects when calling methods and thus can generate false positives: if wr.take_char == '\0' && wr.take_char == '\0'

Examples

# bad
x / x
x.top >= x.top

if a.x != 0 && a.x != 0
  do_something
end

def childs?
  left_child || left_child
end

# good
x + x
1 << 1

Lint/BooleanSymbol

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

No

Yes (Unsafe)

0.50

0.83

This cop checks for :true and :false symbols. In most cases it would be a typo.

Examples

# bad
:true

# good
true
# bad
:false

# good
false

Lint/CircularArgumentReference

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

0.33

-

This cop checks for circular argument references in optional keyword arguments and optional ordinal arguments.

This cop mirrors a warning produced by MRI since 2.2.

Examples

# bad

def bake(pie: pie)
  pie.heat_up
end
# good

def bake(pie:)
  pie.refrigerate
end
# good

def bake(pie: self.pie)
  pie.feed_to(user)
end
# bad

def cook(dry_ingredients = dry_ingredients)
  dry_ingredients.reduce(&:+)
end
# good

def cook(dry_ingredients = self.dry_ingredients)
  dry_ingredients.combine
end

Lint/ConstantDefinitionInBlock

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

0.91

1.3

Do not define constants within a block, since the block’s scope does not isolate or namespace the constant in any way.

If you are trying to define that constant once, define it outside of the block instead, or use a variable or method if defining the constant in the outer scope would be problematic.

For meta-programming, use const_set.

Examples

# bad
task :lint do
  FILES_TO_LINT = Dir['lib/*.rb']
end

# bad
describe 'making a request' do
  class TestRequest; end
end

# bad
module M
  extend ActiveSupport::Concern
  included do
    LIST = []
  end
end

# good
task :lint do
  files_to_lint = Dir['lib/*.rb']
end

# good
describe 'making a request' do
  let(:test_request) { Class.new }
  # see also `stub_const` for RSpec
end

# good
module M
  extend ActiveSupport::Concern
  included do
    const_set(:LIST, [])
  end
end

AllowedMethods: ['enums'] (default)

# good

# `enums` for Typed Enums via `T::Enum` in Sorbet.
# https://sorbet.org/docs/tenum
class TestEnum < T::Enum
  enums do
    Foo = new("foo")
  end
end

Configurable attributes

Name Default value Configurable values

AllowedMethods

enums

Array

Lint/ConstantResolution

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Disabled

Yes

No

0.86

-

Check that certain constants are fully qualified.

This is not enabled by default because it would mark a lot of offenses unnecessarily.

Generally, gems should fully qualify all constants to avoid conflicts with the code that uses the gem. Enable this cop without using Only/Ignore

Large projects will over time end up with one or two constant names that are problematic because of a conflict with a library or just internally using the same name a namespace and a class. To avoid too many unnecessary offenses, Enable this cop with Only: [The, Constant, Names, Causing, Issues]

Examples

# By default checks every constant

# bad
User

# bad
User::Login

# good
::User

# good
::User::Login

Only: ['Login']

# Restrict this cop to only being concerned about certain constants

# bad
Login

# good
::Login

# good
User::Login

Ignore: ['Login']

# Restrict this cop not being concerned about certain constants

# bad
User

# good
::User::Login

# good
Login

Configurable attributes

Name Default value Configurable values

Only

[]

Array

Ignore

[]

Array

Lint/Debugger

Enabled by default Safe Supports autocorrection VersionAdded VersionChanged

Enabled

Yes

No

0.14

1.10

This cop checks for debug calls (such as debugger or binding.pry) that should not be kept for production code.

The cop can be configured using DebuggerMethods. By default, a number of gems debug entrypoints are configured (Kernel, Byebug, Capybara, Pry, Rails, and WebConsole). Additional methods can be added.

Specific default groups can be disabled if necessary:

Lint/Debugger:
  WebConsole: ~
---

=== Examples

[source,ruby]

bad (ok during development)

using pry

def some_method binding.pry do_something end

[source,ruby]

bad (ok during development)

using byebug

def some_method byebug do_something end

[source,ruby]

good

def some_method do_something end

==== DebuggerMethods: [my_debugger]

[source,ruby]

bad (ok during development)

def some_method my_debugger end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| DebuggerReceivers
| `[]`
| Array

| DebuggerMethods
| `{"Kernel"=>["binding.irb"], "Byebug"=>["byebug", "remote_byebug", "Kernel.byebug", "Kernel.remote_byebug"], "Capybara"=>["save_and_open_page", "save_and_open_screenshot"], "Pry"=>["binding.pry", "binding.remote_pry", "binding.pry_remote", "Pry.rescue"], "Rails"=>["debugger", "Kernel.debugger"], "WebConsole"=>["binding.console"]}`
|
|===

== Lint/DeprecatedClassMethods

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.19
| -
|===

This cop checks for uses of the deprecated class method usages.

=== Examples

[source,ruby]

bad

File.exists?(some_path) Dir.exists?(some_path) iterator?

[source,ruby]

good

File.exist?(some_path) Dir.exist?(some_path) block_given?

== Lint/DeprecatedConstants

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| Yes
| 1.8
| -
|===

This cop checks for deprecated constants.

It has `DeprecatedConstants` config. If there is an alternative method, you can set
alternative value as `Alternative`. And you can set the deprecated version as
`DeprecatedVersion`. These options can be omitted if they are not needed.

  DeprecatedConstants:
    'DEPRECATED_CONSTANT':
      Alternative: 'alternative_value'
      DeprecatedVersion: 'deprecated_version'

By default, `NIL`, `TRUE`, `FALSE` and `Random::DEFAULT` are configured.

=== Examples

[source,ruby]

bad

NIL TRUE FALSE Random::DEFAULT # Return value of Ruby 2 is Random instance, Ruby 3.0 is Random class.

good

nil true false Random.new # ::DEFAULT has been deprecated in Ruby 3, .new is compatible with Ruby 2.

=== Configurable attributes

|===
| Name | Default value | Configurable values

| DeprecatedConstants
| `{"NIL"=>{"Alternative"=>"nil", "DeprecatedVersion"=>"2.4"}, "TRUE"=>{"Alternative"=>"true", "DeprecatedVersion"=>"2.4"}, "FALSE"=>{"Alternative"=>"false", "DeprecatedVersion"=>"2.4"}, "Random::DEFAULT"=>{"Alternative"=>"Random.new", "DeprecatedVersion"=>"3.0"}}`
|
|===

== Lint/DeprecatedOpenSSLConstant

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.84
| -
|===

Algorithmic constants for `OpenSSL::Cipher` and `OpenSSL::Digest`
deprecated since OpenSSL version 2.2.0. Prefer passing a string
instead.

=== Examples

[source,ruby]

Example for OpenSSL::Cipher instantiation.

bad

OpenSSL::Cipher::AES.new(128, :GCM)

good

OpenSSL::Cipher.new('aes-128-gcm')

[source,ruby]

Example for OpenSSL::Digest instantiation.

bad

OpenSSL::Digest::SHA256.new

good

OpenSSL::Digest.new('SHA256')

[source,ruby]

Example for ::Digest inherited class methods.

bad

OpenSSL::Digest::SHA256.digest('foo')

good

OpenSSL::Digest.digest('SHA256', 'foo')

== Lint/DisjunctiveAssignmentInConstructor

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.62
| 0.88
|===

This cop checks constructors for disjunctive assignments that should
be plain assignments.

So far, this cop is only concerned with disjunctive assignment of
instance variables.

In ruby, an instance variable is nil until a value is assigned, so the
disjunction is unnecessary. A plain assignment has the same effect.

=== Examples

[source,ruby]

bad

def initialize @x ||= 1 end

good

def initialize @x = 1 end

== Lint/DuplicateBranch

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| No
| 1.3
| 1.7
|===

This cop checks that there are no repeated bodies
within `if/unless`, `case-when` and `rescue` constructs.

With `IgnoreLiteralBranches: true`, branches are not registered
as offenses if they return a basic literal value (string, symbol,
integer, float, rational, complex, `true`, `false`, or `nil`), or
return an array, hash, regexp or range that only contains one of
the above basic literal values.

With `IgnoreConstantBranches: true`, branches are not registered
as offenses if they return a constant value.

=== Examples

[source,ruby]

bad

if foo do_foo do_something_else elsif bar do_foo do_something_else end

good

if foo || bar do_foo do_something_else end

bad

case x when foo do_foo when bar do_foo else do_something_else end

good

case x when foo, bar do_foo else do_something_else end

bad

begin do_something rescue FooError handle_error rescue BarError handle_error end

good

begin do_something rescue FooError, BarError handle_error end

==== IgnoreLiteralBranches: true

[source,ruby]

good

case size when "small" then 100 when "medium" then 250 when "large" then 1000 else 250 end

==== IgnoreLiteralBranches: true

[source,ruby]

good

case size when "small" then SMALL_SIZE when "medium" then MEDIUM_SIZE when "large" then LARGE_SIZE else MEDIUM_SIZE end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| IgnoreLiteralBranches
| `false`
| Boolean

| IgnoreConstantBranches
| `false`
| Boolean
|===

== Lint/DuplicateCaseCondition

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.45
| -
|===

This cop checks that there are no repeated conditions
used in case 'when' expressions.

=== Examples

[source,ruby]

bad

case x when 'first' do_something when 'first' do_something_else end

[source,ruby]

good

case x when 'first' do_something when 'second' do_something_else end

== Lint/DuplicateElsifCondition

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.88
| -
|===

This cop checks that there are no repeated conditions used in if 'elsif'.

=== Examples

[source,ruby]

bad

if x == 1 do_something elsif x == 1 do_something_else end

good

if x == 1 do_something elsif x == 2 do_something_else end

== Lint/DuplicateHashKey

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.34
| 0.77
|===

This cop checks for duplicated keys in hash literals.

This cop mirrors a warning in Ruby 2.2.

=== Examples

[source,ruby]

bad

hash = { food: 'apple', food: 'orange' }

[source,ruby]

good

hash = { food: 'apple', other_food: 'orange' }

== Lint/DuplicateMethods

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.29
| -
|===

This cop checks for duplicated instance (or singleton) method
definitions.

=== Examples

[source,ruby]

bad

def foo 1 end

def foo 2 end

[source,ruby]

bad

def foo 1 end

alias foo bar

[source,ruby]

good

def foo 1 end

def bar 2 end

[source,ruby]

good

def foo 1 end

alias bar foo

== Lint/DuplicateRegexpCharacterClassElement

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| Yes
| 1.1
| -
|===

This cop checks for duplicate elements in Regexp character classes.

=== Examples

[source,ruby]

bad

r = /[xyx]/

bad

r = /[0-9x0-9]/

good

r = /[xy]/

good

r = /[0-9x]/

== Lint/DuplicateRequire

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.90
| -
|===

This cop checks for duplicate `require`s and `require_relative`s.

=== Examples

[source,ruby]

bad

require 'foo' require 'bar' require 'foo'

good

require 'foo' require 'bar'

good

require 'foo' require_relative 'foo'

== Lint/DuplicateRescueException

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.89
| -
|===

This cop checks that there are no repeated exceptions
used in 'rescue' expressions.

=== Examples

[source,ruby]

bad

begin something rescue FirstException handle_exception rescue FirstException handle_other_exception end

good

begin something rescue FirstException handle_exception rescue SecondException handle_other_exception end

== Lint/EachWithObjectArgument

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.31
| -
|===

This cop checks if each_with_object is called with an immutable
argument. Since the argument is the object that the given block shall
make calls on to build something based on the enumerable that
each_with_object iterates over, an immutable argument makes no sense.
It's definitely a bug.

=== Examples

[source,ruby]

bad

sum = numbers.each_with_object(0) { |e, a| a += e }

[source,ruby]

good

num = 0 sum = numbers.each_with_object(num) { |e, a| a += e }

== Lint/ElseLayout

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.17
| 1.2
|===

This cop checks for odd `else` block layout - like
having an expression on the same line as the `else` keyword,
which is usually a mistake.

Its auto-correction tweaks layout to keep the syntax. So, this auto-correction
is compatible correction for bad case syntax, but if your code makes a mistake
with `elsif` and `else`, you will have to correct it manually.

=== Examples

[source,ruby]

bad

if something # …​ else do_this do_that end

[source,ruby]

good

This code is compatible with the bad case. It will be auto-corrected like this.

if something # …​ else do_this do_that end

This code is incompatible with the bad case.

If do_this is a condition, elsif should be used instead of else.

if something # …​ elsif do_this do_that end

== Lint/EmptyBlock

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| No
| 1.1
| 1.3
|===

This cop checks for blocks without a body.
Such empty blocks are typically an oversight or we should provide a comment
be clearer what we're aiming for.

Empty lambdas are ignored by default.

=== Examples

[source,ruby]

bad

items.each { |item| }

good

items.each { |item| puts item }

==== AllowComments: true (default)

[source,ruby]

good

items.each do |item| # TODO: implement later (inner comment) end

items.each { |item| } # TODO: implement later (inline comment)

==== AllowComments: false

[source,ruby]

bad

items.each do |item| # TODO: implement later (inner comment) end

items.each { |item| } # TODO: implement later (inline comment)

==== AllowEmptyLambdas: true (default)

[source,ruby]

good

allow(subject).to receive(:callable).and_return(→ {})

placeholder = lambda do end (callable || placeholder).call

==== AllowEmptyLambdas: false

[source,ruby]

bad

allow(subject).to receive(:callable).and_return(→ {})

placeholder = lambda do end (callable || placeholder).call

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowComments
| `true`
| Boolean

| AllowEmptyLambdas
| `true`
| Boolean
|===

== Lint/EmptyClass

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| No
| 1.3
| -
|===

This cop checks for classes and metaclasses without a body.
Such empty classes and metaclasses are typically an oversight or we should provide a comment
to be clearer what we're aiming for.

=== Examples

[source,ruby]

bad

class Foo end

class Bar class << self end end

class << obj end

good

class Foo def do_something # …​ code end end

class Bar class << self attr_reader :bar end end

class << obj attr_reader :bar end

==== AllowComments: false (default)

[source,ruby]

bad

class Foo # TODO: implement later end

class Bar class << self # TODO: implement later end end

class << obj # TODO: implement later end

==== AllowComments: true

[source,ruby]

good

class Foo # TODO: implement later end

class Bar class << self # TODO: implement later end end

class << obj # TODO: implement later end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowComments
| `false`
| Boolean
|===

== Lint/EmptyConditionalBody

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.89
| -
|===

This cop checks for the presence of `if`, `elsif` and `unless` branches without a body.

=== Examples

[source,ruby]

bad

if condition end

bad

unless condition end

bad

if condition do_something elsif other_condition end

good

if condition do_something end

good

unless condition do_something end

good

if condition do_something elsif other_condition do_something_else end

==== AllowComments: true (default)

[source,ruby]

good

if condition do_something elsif other_condition # noop end

==== AllowComments: false

[source,ruby]

bad

if condition do_something elsif other_condition # noop end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowComments
| `true`
| Boolean
|===

== Lint/EmptyEnsure

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.10
| 0.48
|===

This cop checks for empty `ensure` blocks

=== Examples

[source,ruby]

bad

def some_method do_something ensure end

[source,ruby]

bad

begin do_something ensure end

[source,ruby]

good

def some_method do_something ensure do_something_else end

[source,ruby]

good

begin do_something ensure do_something_else end

== Lint/EmptyExpression

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.45
| -
|===

This cop checks for the presence of empty expressions.

=== Examples

[source,ruby]

bad

foo = () if () bar end

[source,ruby]

good

foo = (some_expression) if (some_expression) bar end

== Lint/EmptyFile

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.90
| -
|===

This cop enforces that Ruby source files are not empty.

=== Examples

[source,ruby]

bad

Empty file

good

File containing non commented source lines

==== AllowComments: true (default)

[source,ruby]

good

File consisting only of comments

==== AllowComments: false

[source,ruby]

bad

File consisting only of comments

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowComments
| `true`
| Boolean
|===

== Lint/EmptyInterpolation

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.20
| 0.45
|===

This cop checks for empty interpolation.

=== Examples

[source,ruby]

bad

"result is #{}"

[source,ruby]

good

"result is #{some_result}"

== Lint/EmptyWhen

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.45
| 0.83
|===

This cop checks for the presence of `when` branches without a body.

=== Examples

[source,ruby]

bad

case foo when bar do_something when baz end

[source,ruby]

good

case condition when foo do_something when bar nil end

==== AllowComments: true (default)

[source,ruby]

good

case condition when foo do_something when bar # noop end

==== AllowComments: false

[source,ruby]

bad

case condition when foo do_something when bar # do nothing end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowComments
| `true`
| Boolean
|===

== Lint/EnsureReturn

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.9
| 0.83
|===

This cop checks for `return` from an `ensure` block.
`return` from an ensure block is a dangerous code smell as it
will take precedence over any exception being raised,
and the exception will be silently thrown away as if it were rescued.

If you want to rescue some (or all) exceptions, best to do it explicitly

=== Examples

[source,ruby]

bad

def foo do_something ensure cleanup return self end

[source,ruby]

good

def foo do_something self ensure cleanup end

also good

def foo begin do_something rescue SomeException # Let’s ignore this exception end self ensure cleanup end

=== References

* https://rubystyle.guide#no-return-ensure

== Lint/ErbNewArguments

NOTE: Required Ruby version: 2.6

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.56
| -
|===

This cop emulates the following Ruby warnings in Ruby 2.6.

% cat example.rb
ERB.new('hi', nil, '-', '@output_buffer')
% ruby -rerb example.rb
example.rb:1: warning: Passing safe_level with the 2nd argument of
ERB.new is deprecated. Do not use it, and specify other arguments as
keyword arguments.
example.rb:1: warning: Passing trim_mode with the 3rd argument of
ERB.new is deprecated. Use keyword argument like
ERB.new(str, trim_mode:...) instead.
example.rb:1: warning: Passing eoutvar with the 4th argument of ERB.new
is deprecated. Use keyword argument like ERB.new(str, eoutvar: ...)
instead.

Now non-keyword arguments other than first one are softly deprecated
and will be removed when Ruby 2.5 becomes EOL.
`ERB.new` with non-keyword arguments is deprecated since ERB 2.2.0.
Use `:trim_mode` and `:eoutvar` keyword arguments to `ERB.new`.
This cop identifies places where `ERB.new(str, trim_mode, eoutvar)` can
be replaced by `ERB.new(str, :trim_mode: trim_mode, eoutvar: eoutvar)`.

=== Examples

[source,ruby]

Target codes supports Ruby 2.6 and higher only

bad

ERB.new(str, nil, '-', '@output_buffer')

good

ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')

Target codes supports Ruby 2.5 and lower only

good

ERB.new(str, nil, '-', '@output_buffer')

Target codes supports Ruby 2.6, 2.5 and lower

bad

ERB.new(str, nil, '-', '@output_buffer')

good

Ruby standard library style

https://github.com/ruby/ruby/commit/3406c5d

if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+ ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer') else ERB.new(str, nil, '-', '@output_buffer') end

good

Use RUBY_VERSION style

if RUBY_VERSION >= '2.6' ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer') else ERB.new(str, nil, '-', '@output_buffer') end

== Lint/FlipFlop

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.16
| -
|===

This cop looks for uses of flip-flop operator
based on the Ruby Style Guide.

Here is the history of flip-flops in Ruby.
flip-flop operator is deprecated in Ruby 2.6.0 and
the deprecation has been reverted by Ruby 2.7.0 and
backported to Ruby 2.6.
See: https://bugs.ruby-lang.org/issues/5400

=== Examples

[source,ruby]

bad

(1..20).each do |x| puts x if (x == 5) .. (x == 10) end

good

(1..20).each do |x| puts x if (x >= 5) && (x ⇐ 10) end

=== References

* https://rubystyle.guide#no-flip-flops

== Lint/FloatComparison

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.89
| -
|===

This cop checks for the presence of precise comparison of floating point numbers.

Floating point values are inherently inaccurate, and comparing them for exact equality
is almost never the desired semantics. Comparison via the `==/!=` operators checks
floating-point value representation to be exactly the same, which is very unlikely
if you perform any arithmetic operations involving precision loss.

=== Examples

[source,ruby]

bad

x == 0.1 x != 0.1

good - using BigDecimal

x.to_d == 0.1.to_d

good

(x - 0.1).abs < Float::EPSILON

good

tolerance = 0.0001 (x - 0.1).abs < tolerance

Or some other epsilon based type of comparison:

https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/

=== References

* https://rubystyle.guide#float-comparison

== Lint/FloatOutOfRange

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.36
| -
|===

This cop identifies Float literals which are, like, really really really
really really really really really big. Too big. No-one needs Floats
that big. If you need a float that big, something is wrong with you.

=== Examples

[source,ruby]

bad

float = 3.0e400

[source,ruby]

good

float = 42.9

== Lint/FormatParameterMismatch

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.33
| -
|===

This lint sees if there is a mismatch between the number of
expected fields for format/sprintf/#% and what is actually
passed as arguments.

In addition it checks whether different formats are used in the same
format string. Do not mix numbered, unnumbered, and named formats in
the same format string.

=== Examples

[source,ruby]

bad

format('A value: %s and another: %i', a_value)

[source,ruby]

good

format('A value: %s and another: %i', a_value, another)

[source,ruby]

bad

format('Unnumbered format: %s and numbered: %2$s', a_value, another)

[source,ruby]

good

format('Numbered format: %1$s and numbered %2$s', a_value, another)

== Lint/HashCompareByIdentity

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| No
| 0.93
| -
|===

Prefer using `Hash#compare_by_identity` than using `object_id` for hash keys.

This cop is marked as unsafe as a hash possibly can contain other keys
besides `object_id`s.

=== Examples

[source,ruby]

bad

hash = {} hash[foo.object_id] = :bar hash.key?(baz.object_id)

good

hash = {}.compare_by_identity hash[foo] = :bar hash.key?(baz)

=== References

* https://rubystyle.guide#identity-comparison

== Lint/HeredocMethodCallPosition

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Disabled
| Yes
| Yes
| 0.68
| -
|===

This cop checks for the ordering of a method call where
the receiver of the call is a HEREDOC.

=== Examples

[source,ruby]

bad

<<-SQL
  bar
SQL
.strip_indent
<<-SQL
  bar
SQL
.strip_indent
.trim

good

<<~SQL
  bar
SQL
<<~SQL.trim
  bar
SQL
=== References

* https://rubystyle.guide#heredoc-method-calls

== Lint/IdentityComparison

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.91
| -
|===

Prefer `equal?` over `==` when comparing `object_id`.

`Object#equal?` is provided to compare objects for identity, and in contrast
`Object#==` is provided for the purpose of doing value comparison.

=== Examples

[source,ruby]

bad

foo.object_id == bar.object_id

good

foo.equal?(bar)

=== References

* https://rubystyle.guide#identity-comparison

== Lint/ImplicitStringConcatenation

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.36
| -
|===

This cop checks for implicit string concatenation of string literals
which are on the same line.

=== Examples

[source,ruby]

bad

array = ['Item 1' 'Item 2']

[source,ruby]

good

array = ['Item 1Item 2'] array = ['Item 1' + 'Item 2'] array = [ 'Item 1' \ 'Item 2' ]

== Lint/IneffectiveAccessModifier

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.36
| -
|===

This cop checks for `private` or `protected` access modifiers which are
applied to a singleton method. These access modifiers do not make
singleton methods private/protected. `private_class_method` can be
used for that.

=== Examples

[source,ruby]

bad

class C private

  def self.method
    puts 'hi'
  end
end
[source,ruby]

good

class C def self.method puts 'hi' end

  private_class_method :method
end
[source,ruby]

good

class C class << self private

    def method
      puts 'hi'
    end
  end
end
== Lint/InheritException

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.41
| -
|===

This cop looks for error classes inheriting from `Exception`
and its standard library subclasses, excluding subclasses of
`StandardError`. It is configurable to suggest using either
`RuntimeError` (default) or `StandardError` instead.

=== Examples

==== EnforcedStyle: runtime_error (default)

[source,ruby]

bad

class C < Exception; end

C = Class.new(Exception)

good

class C < RuntimeError; end

C = Class.new(RuntimeError)

==== EnforcedStyle: standard_error

[source,ruby]

bad

class C < Exception; end

C = Class.new(Exception)

good

class C < StandardError; end

C = Class.new(StandardError)

=== Configurable attributes

|===
| Name | Default value | Configurable values

| EnforcedStyle
| `runtime_error`
| `runtime_error`, `standard_error`
|===

== Lint/InterpolationCheck

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.50
| 0.87
|===

This cop checks for interpolation in a single quoted string.

=== Examples

[source,ruby]

bad

foo = 'something with #{interpolation} inside'

[source,ruby]

good

foo = "something with #{interpolation} inside"

== Lint/LambdaWithoutLiteralBlock

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| Yes
| 1.8
| -
|===

This cop checks uses of lambda without a literal block.
It emulates the following warning in Ruby 3.0:

  % ruby -vwe 'lambda(&proc {})'
  ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
  -e:1: warning: lambda without a literal block is deprecated; use the proc without
  lambda instead

This way, proc object is never converted to lambda.
Auto-correction replaces with compatible proc argument.

=== Examples

[source,ruby]

bad

lambda(&proc { do_something }) lambda(&Proc.new { do_something })

good

proc { do_something } Proc.new { do_something } lambda { do_something } # If you use lambda.

== Lint/LiteralAsCondition

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.51
| -
|===

This cop checks for literals used as the conditions or as
operands in and/or expressions serving as the conditions of
if/while/until.

=== Examples

[source,ruby]

bad

if 20 do_something end

bad

if some_var && true do_something end

good

if some_var && some_condition do_something end

good

When using a boolean value for an infinite loop.

while true break if condition end

== Lint/LiteralInInterpolation

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.19
| 0.32
|===

This cop checks for interpolated literals.

=== Examples

[source,ruby]

bad

"result is #{10}"

[source,ruby]

good

"result is 10"

== Lint/Loop

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.9
| 1.3
|===

This cop checks for uses of `begin...end while/until something`.

The cop is marked as unsafe because behaviour can change in some cases, including
if a local variable inside the loop body is accessed outside of it, or if the
loop body raises a `StopIteration` exception (which `Kernel#loop` rescues).

=== Examples

[source,ruby]

bad

using while

begin do_something end while some_condition

[source,ruby]

bad

using until

begin do_something end until some_condition

[source,ruby]

good

while replacement

loop do do_something break unless some_condition end

[source,ruby]

good

until replacement

loop do do_something break if some_condition end

=== References

* https://rubystyle.guide#loop-with-break

== Lint/MissingCopEnableDirective

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.52
| -
|===

This cop checks that there is an `# rubocop:enable ...` statement
after a `# rubocop:disable ...` statement. This will prevent leaving
cop disables on wide ranges of code, that latter contributors to
a file wouldn't be aware of.

=== Examples

[source,ruby]

Lint/MissingCopEnableDirective:

MaximumRangeSize: .inf

good

rubocop:disable Layout/SpaceAroundOperators

x= 0 # rubocop:enable Layout/SpaceAroundOperators # y = 1 # EOF

bad

rubocop:disable Layout/SpaceAroundOperators

x= 0 # EOF

[source,ruby]

Lint/MissingCopEnableDirective:

MaximumRangeSize: 2

good

rubocop:disable Layout/SpaceAroundOperators

x= 0 # With the previous, there are 2 lines on which cop is disabled. # rubocop:enable Layout/SpaceAroundOperators

bad

rubocop:disable Layout/SpaceAroundOperators

x= 0 x += 1 # Including this, that’s 3 lines on which the cop is disabled. # rubocop:enable Layout/SpaceAroundOperators

=== Configurable attributes

|===
| Name | Default value | Configurable values

| MaximumRangeSize
| `Infinity`
| Float
|===

== Lint/MissingSuper

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.89
| 1.4
|===

This cop checks for the presence of constructors and lifecycle callbacks
without calls to `super`.

This cop does not consider `method_missing` (and `respond_to_missing?`)
because in some cases it makes sense to overtake what is considered a
missing method. In other cases, the theoretical ideal handling could be
challenging or verbose for no actual gain.

=== Examples

[source,ruby]

bad

class Employee < Person def initialize(name, salary) @salary = salary end end

good

class Employee < Person def initialize(name, salary) super(name) @salary = salary end end

bad

class Parent def self.inherited(base) do_something end end

good

class Parent def self.inherited(base) super do_something end end

== Lint/MixedRegexpCaptureTypes

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.85
| -
|===

Do not mix named captures and numbered captures in a Regexp literal
because numbered capture is ignored if they're mixed.
Replace numbered captures with non-capturing groupings or
named captures.

  # bad
  /(?<foo>FOO)(BAR)/

  # good
  /(?<foo>FOO)(?<bar>BAR)/

  # good
  /(?<foo>FOO)(?:BAR)/

  # good
  /(FOO)(BAR)/

== Lint/MultipleComparison

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.47
| 1.1
|===

In math and Python, we can use `x < y < z` style comparison to compare
multiple value. However, we can't use the comparison in Ruby. However,
the comparison is not syntax error. This cop checks the bad usage of
comparison operators.

=== Examples

[source,ruby]

bad

x < y < z 10 ⇐ x ⇐ 20

good

x < y && y < z 10 ⇐ x && x ⇐ 20

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowMethodComparison
| `true`
| Boolean
|===

== Lint/NestedMethodDefinition

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.32
| -
|===

This cop checks for nested method definitions.

=== Examples

[source,ruby]

bad

bar definition actually produces methods in the same scope

as the outer foo method. Furthermore, the bar method

will be redefined every time foo is invoked.

def foo def bar end end

[source,ruby]

good

def foo bar = → { puts 'hello' } bar.call end

[source,ruby]

good

def foo self.class.class_eval do def bar end end end

def foo self.class.module_exec do def bar end end end

[source,ruby]

good

def foo class << self def bar end end end

=== References

* https://rubystyle.guide#no-nested-methods

== Lint/NestedPercentLiteral

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.52
| -
|===

This cop checks for nested percent literals.

=== Examples

[source,ruby]

bad

The percent literal for nested_attributes is parsed as four tokens,

yielding the array [:name, :content, :"%i[incorrectly", :"nested]"].

attributes = { valid_attributes: %i[name content], nested_attributes: %i[name content %i[incorrectly nested]] }

good

Neither is incompatible with the bad case, but probably the intended code.

attributes = { valid_attributes: %i[name content], nested_attributes: [:name, :content, %i[incorrectly nested]] }

attributes = { valid_attributes: %i[name content], nested_attributes: [:name, :content, [:incorrectly, :nested]] }

== Lint/NextWithoutAccumulator

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.36
| -
|===

Don't omit the accumulator when calling `next` in a `reduce` block.

=== Examples

[source,ruby]

bad

result = (1..4).reduce(0) do |acc, i| next if i.odd? acc + i end

[source,ruby]

good

result = (1..4).reduce(0) do |acc, i| next acc if i.odd? acc + i end

== Lint/NoReturnInBeginEndBlocks

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| No
| 1.2
| -
|===

Checks for the presence of a `return` inside a `begin..end` block
in assignment contexts.
In this situation, the `return` will result in an exit from the current
method, possibly leading to unexpected behavior.

=== Examples

[source,ruby]

bad

@some_variable ||= begin return some_value if some_condition_is_met

  do_something
end
[source,ruby]

good

@some_variable ||= begin if some_condition_is_met some_value else do_something end end

good

some_variable = if some_condition_is_met return if another_condition_is_met

  some_value
else
  do_something
end
== Lint/NonDeterministicRequireOrder

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.78
| -
|===

`Dir[...]` and `Dir.glob(...)` do not make any guarantees about
the order in which files are returned. The final order is
determined by the operating system and file system.
This means that using them in cases where the order matters,
such as requiring files, can lead to intermittent failures
that are hard to debug. To ensure this doesn't happen,
always sort the list.

`Dir.glob` and `Dir[]` sort globbed results by default in Ruby 3.0.
So all bad cases are acceptable when Ruby 3.0 or higher are used.

This cop will be deprecated and removed when supporting only Ruby 3.0 and higher.

=== Examples

[source,ruby]

bad

Dir["./lib/*/.rb"].each do |file| require file end

good

Dir["./lib/*/.rb"].sort.each do |file| require file end

bad

Dir.glob(Rails.root.join(dir, 'test', '*.rb')) do |file| require file end

good

Dir.glob(Rails.root.join(dir, 'test', '*.rb')).sort.each do |file| require file end

bad

Dir['./lib/*/.rb'].each(&method(:require))

good

Dir['./lib/*/.rb'].sort.each(&method(:require))

bad

Dir.glob(Rails.root.join('test', '*.rb'), &method(:require))

good

Dir.glob(Rails.root.join('test', '*.rb')).sort.each(&method(:require))

good - Respect intent if sort keyword option is specified in Ruby 3.0 or higher.

Dir.glob(Rails.root.join(dir, 'test', '*.rb'), sort: false).each(&method(:require))

== Lint/NonLocalExitFromIterator

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.30
| -
|===

This cop checks for non-local exits from iterators without a return
value. It registers an offense under these conditions:

* No value is returned,
* the block is preceded by a method chain,
* the block has arguments,
* the method which receives the block is not `define_method`
or `define_singleton_method`,
* the return is not contained in an inner scope, e.g. a lambda or a
method definition.

=== Examples

[source,ruby]

class ItemApi rescue_from ValidationError do |e| # non-iteration block with arg return { message: 'validation error' } unless e.errors # allowed error_array = e.errors.map do |error| # block with method chain return if error.suppress? # warned return "{error.param}: invalid" unless error.message # allowed "{error.param}: #{error.message}" end { message: 'validation error', errors: error_array } end

  def update_items
    transaction do # block without arguments
      return unless update_necessary? # allowed
      find_each do |item| # block without method chain
        return if item.stock == 0 # false-negative...
        item.update!(foobar: true)
      end
    end
  end
end
== Lint/NumberConversion

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Disabled
| Yes
| Yes (Unsafe)
| 0.53
| 1.1
|===

This cop warns the usage of unsafe number conversions. Unsafe
number conversion can cause unexpected error if auto type conversion
fails. Cop prefer parsing with number class instead.

Conversion with `Integer`, `Float`, etc. will raise an `ArgumentError`
if given input that is not numeric (eg. an empty string), whereas
`to_i`, etc. will try to convert regardless of input (`''.to_i => 0`).
As such, this cop is disabled by default because it's not necessarily
always correct to raise if a value is not numeric.

NOTE: Some values cannot be converted properly using one of the `Kernel`
method (for instance, `Time` and `DateTime` values are allowed by this
cop by default). Similarly, Rails' duration methods do not work well
with `Integer()` and can be ignored with `IgnoredMethods`.

=== Examples

[source,ruby]

bad

'10'.to_i '10.2'.to_f '10'.to_c ['1', '2', '3'].map(&:to_i) foo.try(:to_f) bar.send(:to_c)

good

Integer('10', 10) Float('10.2') Complex('10') ['1', '2', '3'].map { |i| Integer(i, 10) } foo.try { |i| Float(i) } bar.send { |i| Complex(i) }

==== IgnoredMethods: [minutes]

[source,ruby]

good

10.minutes.to_i

==== IgnoredClasses: [Time, DateTime] (default)

[source,ruby]

good

Time.now.to_datetime.to_i

=== Configurable attributes

|===
| Name | Default value | Configurable values

| IgnoredMethods
| `[]`
| Array

| IgnoredClasses
| `Time`, `DateTime`
| Array
|===

== Lint/NumberedParameterAssignment

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| No
| 1.9
| -
|===

This cop checks for uses of numbered parameter assignment.
It emulates the following warning in Ruby 2.7:

  % ruby -ve '_1 = :value'
  ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]
  -e:1: warning: `_1' is reserved for numbered parameter; consider another name

Assiging to numbered parameter (from `_1` to `_9`) cause an error in Ruby 3.0.

  % ruby -ve '_1 = :value'
  ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
  -e:1: _1 is reserved for numbered parameter

NOTE: The parametered parameters are from `_1` to `_9`. This cop checks `_0`, and over `_10`
as well to prevent confusion.

=== Examples

[source,ruby]

bad

_1 = :value

good

non_numbered_parameter_name = :value

== Lint/OrAssignmentToConstant

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| No
| Yes (Unsafe)
| 1.9
| -
|===

This cop checks for unintended or-assignment to a constant.

Constants should always be assigned in the same location. And its value
should always be the same. If constants are assigned in multiple
locations, the result may vary depending on the order of `require`.

Also, if you already have such an implementation, auto-correction may
change the result.

=== Examples

[source,ruby]

bad

CONST ||= 1

good

CONST = 1

== Lint/OrderedMagicComments

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.53
| -
|===

Checks the proper ordering of magic comments and whether
a magic comment is not placed before a shebang.

=== Examples

[source,ruby]

bad

frozen_string_literal: true

encoding: ascii

p [''.frozen?, ''.encoding] #⇒ [true, #<Encoding:UTF-8>]

good

encoding: ascii

frozen_string_literal: true

p [''.frozen?, ''.encoding] #⇒ [true, #<Encoding:US-ASCII>]

good

#!/usr/bin/env ruby # encoding: ascii # frozen_string_literal: true p [''.frozen?, ''.encoding] #⇒ [true, #<Encoding:US-ASCII>]

== Lint/OutOfRangeRegexpRef

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| No
| 0.89
| -
|===

This cops looks for references of Regexp captures that are out of range
and thus always returns nil.

=== Examples

[source,ruby]

/(foo)bar/ =~ 'foobar'

bad - always returns nil

puts $2 # ⇒ nil

good

puts $1 # ⇒ foo

== Lint/ParenthesesAsGroupedExpression

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.12
| 0.83
|===

Checks for space between the name of a called method and a left
parenthesis.

=== Examples

[source,ruby]

bad

do_something (foo)

good

do_something(foo) do_something (2 + 3) * 4 do_something (foo * bar).baz

=== References

* https://rubystyle.guide#parens-no-spaces

== Lint/PercentStringArray

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.41
| -
|===

This cop checks for quotes and commas in %w, e.g. `%w('foo', "bar")`

It is more likely that the additional characters are unintended (for
example, mistranslating an array of literals to percent string notation)
rather than meant to be part of the resulting strings.

=== Examples

[source,ruby]

bad

%w('foo', "bar")

[source,ruby]

good

%w(foo bar)

== Lint/PercentSymbolArray

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.41
| -
|===

This cop checks for colons and commas in %i, e.g. `%i(:foo, :bar)`

It is more likely that the additional characters are unintended (for
example, mistranslating an array of literals to percent string notation)
rather than meant to be part of the resulting symbols.

=== Examples

[source,ruby]

bad

%i(:foo, :bar)

[source,ruby]

good

%i(foo bar)

== Lint/RaiseException

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.81
| 0.86
|===

This cop checks for `raise` or `fail` statements which are
raising `Exception` class.

You can specify a module name that will be an implicit namespace
using `AllowedImplicitNamespaces` option. The cop cause a false positive
for namespaced `Exception` when a namespace is omitted. This option can
prevent the false positive by specifying a namespace to be omitted for
`Exception`. Alternatively, make `Exception` a fully qualified class
name with an explicit namespace.

=== Examples

[source,ruby]

bad

raise Exception, 'Error message here'

good

raise StandardError, 'Error message here'

==== AllowedImplicitNamespaces: ['Gem']

[source,ruby]

good

module Gem def self.foo raise Exception # This exception means Gem::Exception. end end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowedImplicitNamespaces
| `Gem`
| Array
|===

=== References

* https://rubystyle.guide#raise-exception

== Lint/RandOne

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.36
| -
|===

This cop checks for `rand(1)` calls.
Such calls always return `0`.

=== Examples

[source,ruby]

bad

rand 1 Kernel.rand(-1) rand 1.0 rand(-1.0)

[source,ruby]

good

0 # just use 0 instead

== Lint/RedundantCopDisableDirective

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.76
| -
|===

This cop detects instances of rubocop:disable comments that can be
removed without causing any offenses to be reported. It's implemented
as a cop in that it inherits from the Cop base class and calls
add_offense. The unusual part of its implementation is that it doesn't
have any on_* methods or an investigate method. This means that it
doesn't take part in the investigation phase when the other cops do
their work. Instead, it waits until it's called in a later stage of the
execution. The reason it can't be implemented as a normal cop is that
it depends on the results of all other cops to do its work.

=== Examples

[source,ruby]

bad

rubocop:disable Layout/LineLength

x += 1 # rubocop:enable Layout/LineLength

good

x += 1

== Lint/RedundantCopEnableDirective

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.76
| -
|===

This cop detects instances of rubocop:enable comments that can be
removed.

When comment enables all cops at once `rubocop:enable all`
that cop checks whether any cop was actually enabled.

=== Examples

[source,ruby]

bad

foo = 1 # rubocop:enable Layout/LineLength

good

foo = 1

[source,ruby]

bad

rubocop:disable Style/StringLiterals

foo = "1" # rubocop:enable Style/StringLiterals baz # rubocop:enable all

good

rubocop:disable Style/StringLiterals

foo = "1" # rubocop:enable all baz

== Lint/RedundantDirGlobSort

NOTE: Required Ruby version: 3.0

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| Yes
| 1.8
| -
|===

Sort globbed results by default in Ruby 3.0.
This cop checks for redundant `sort` method to `Dir.glob` and `Dir[]`.

=== Examples

[source,ruby]

bad

Dir.glob('./lib/*/.rb').sort.each do |file| end

Dir['./lib/*/.rb'].sort.each do |file| end

good

Dir.glob('./lib/*/.rb').each do |file| end

Dir['./lib/*/.rb'].each do |file| end

== Lint/RedundantRequireStatement

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.76
| -
|===

Checks for unnecessary `require` statement.

The following features are unnecessary `require` statement because
they are already loaded.

  ruby -ve 'p $LOADED_FEATURES.reject { |feature| %r|/| =~ feature }'
  ruby 2.2.8p477 (2017-09-14 revision 59906) [x86_64-darwin13]
  ["enumerator.so", "rational.so", "complex.so", "thread.rb"]

This cop targets Ruby 2.2 or higher containing these 4 features.

=== Examples

[source,ruby]

bad

require 'unloaded_feature' require 'thread'

good

require 'unloaded_feature'

== Lint/RedundantSafeNavigation

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.93
| -
|===

This cop checks for redundant safe navigation calls.
`instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, and `equal?` methods
are checked by default. These are customizable with `AllowedMethods` option.

This cop is marked as unsafe, because auto-correction can change the
return type of the expression. An offending expression that previously
could return `nil` will be auto-corrected to never return `nil`.

In the example below, the safe navigation operator (`&.`) is unnecessary
because `NilClass` has methods like `respond_to?` and `is_a?`.

=== Examples

[source,ruby]

bad

do_something if attrs&.respond_to?(:[])

good

do_something if attrs.respond_to?(:[])

bad

while node&.is_a?(BeginNode) node = node.parent end

good

while node.is_a?(BeginNode) node = node.parent end

good - without &. this will always return true

foo&.respond_to?(:to_a)

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowedMethods
| `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, `equal?`
| Array
|===

== Lint/RedundantSplatExpansion

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.76
| 1.7
|===

This cop checks for unneeded usages of splat expansion

=== Examples

[source,ruby]

bad

a = *[1, 2, 3] a = *'a' a = *1

good

c = [1, 2, 3] a = *c a, b = *c a, *b = *c a = *1..10 a = ['a']

bad

do_something(*['foo', 'bar', 'baz'])

good

do_something('foo', 'bar', 'baz')

bad

begin foo rescue *[StandardError, ApplicationError] bar end

good

begin foo rescue StandardError, ApplicationError bar end

bad

case foo when *[1, 2, 3] bar else baz end

good

case foo when 1, 2, 3 bar else baz end

==== AllowPercentLiteralArrayArgument: true (default)

[source,ruby]

good

do_something(*%w[foo bar baz])

==== AllowPercentLiteralArrayArgument: false

[source,ruby]

bad

do_something(*%w[foo bar baz])

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowPercentLiteralArrayArgument
| `true`
| Boolean
|===

== Lint/RedundantStringCoercion

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.19
| 0.77
|===

This cop checks for string conversion in string interpolation,
which is redundant.

=== Examples

[source,ruby]

bad

"result is #{something.to_s}"

[source,ruby]

good

"result is #{something}"

=== References

* https://rubystyle.guide#no-to-s

== Lint/RedundantWithIndex

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.50
| -
|===

This cop checks for redundant `with_index`.

=== Examples

[source,ruby]

bad

ary.each_with_index do |v| v end

good

ary.each do |v| v end

bad

ary.each.with_index do |v| v end

good

ary.each do |v| v end

== Lint/RedundantWithObject

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.51
| -
|===

This cop checks for redundant `with_object`.

=== Examples

[source,ruby]

bad

ary.each_with_object([]) do |v| v end

good

ary.each do |v| v end

bad

ary.each.with_object([]) do |v| v end

good

ary.each do |v| v end

== Lint/RegexpAsCondition

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.51
| 0.86
|===

This cop checks for regexp literals used as `match-current-line`.
If a regexp literal is in condition, the regexp matches `$_` implicitly.

=== Examples

[source,ruby]

bad

if /foo/ do_something end

good

if /foo/ =~ $_ do_something end

== Lint/RequireParentheses

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.18
| -
|===

This cop checks for expressions where there is a call to a predicate
method with at least one argument, where no parentheses are used around
the parameter list, and a boolean operator, && or ||, is used in the
last argument.

The idea behind warning for these constructs is that the user might
be under the impression that the return value from the method call is
an operand of &&/||.

=== Examples

[source,ruby]

bad

if day.is? :tuesday && month == :jan # …​ end

[source,ruby]

good

if day.is?(:tuesday) && month == :jan # …​ end

== Lint/RescueException

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.9
| 0.27
|===

This cop checks for `rescue` blocks targeting the Exception class.

=== Examples

[source,ruby]

bad

begin do_something rescue Exception handle_exception end

[source,ruby]

good

begin do_something rescue ArgumentError handle_exception end

=== References

* https://rubystyle.guide#no-blind-rescues

== Lint/RescueType

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.49
| -
|===

Check for arguments to `rescue` that will result in a `TypeError`
if an exception is raised.

=== Examples

[source,ruby]

bad

begin bar rescue nil baz end

bad

def foo bar rescue 1, 'a', "#{b}", 0.0, [], {} baz end

good

begin bar rescue baz end

good

def foo bar rescue NameError baz end

== Lint/ReturnInVoidContext

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.50
| -
|===

This cop checks for the use of a return with a value in a context
where the value will be ignored. (initialize and setter methods)

=== Examples

[source,ruby]

bad

def initialize foo return :qux if bar? baz end

def foo=(bar) return 42 end

[source,ruby]

good

def initialize foo return if bar? baz end

def foo=(bar) return end

== Lint/SafeNavigationChain

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.47
| 0.77
|===

The safe navigation operator returns nil if the receiver is
nil. If you chain an ordinary method call after a safe
navigation operator, it raises NoMethodError. We should use a
safe navigation operator after a safe navigation operator.
This cop checks for the problem outlined above.

=== Examples

[source,ruby]

bad

x&.foo.bar x&.foo + bar x&.foo[bar]

[source,ruby]

good

x&.foo&.bar x&.foo || bar

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowedMethods
| `present?`, `blank?`, `presence`, `try`, `try!`, `in?`
| Array
|===

== Lint/SafeNavigationConsistency

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.55
| 0.77
|===

This cop check to make sure that if safe navigation is used for a method
call in an `&&` or `||` condition that safe navigation is used for all
method calls on that same object.

=== Examples

[source,ruby]

bad

foo&.bar && foo.baz

bad

foo.bar || foo&.baz

bad

foo&.bar && (foobar.baz || foo.baz)

good

foo.bar && foo.baz

good

foo&.bar || foo&.baz

good

foo&.bar && (foobar.baz || foo&.baz)

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowedMethods
| `present?`, `blank?`, `presence`, `try`, `try!`
| Array
|===

== Lint/SafeNavigationWithEmpty

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.62
| 0.87
|===

This cop checks to make sure safe navigation isn't used with `empty?` in
a conditional.

While the safe navigation operator is generally a good idea, when
checking `foo&.empty?` in a conditional, `foo` being `nil` will actually
do the opposite of what the author intends.

=== Examples

[source,ruby]

bad

return if foo&.empty? return unless foo&.empty?

good

return if foo && foo.empty? return unless foo && foo.empty?

== Lint/ScriptPermission

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.49
| 0.50
|===

This cop checks if a file which has a shebang line as
its first line is granted execute permission.

=== Examples

[source,ruby]

bad

A file which has a shebang line as its first line is not

granted execute permission.

#!/usr/bin/env ruby puts 'hello, world'

good

A file which has a shebang line as its first line is

granted execute permission.

#!/usr/bin/env ruby puts 'hello, world'

good

A file which has not a shebang line as its first line is not

granted execute permission.

puts 'hello, world'

== Lint/SelfAssignment

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.89
| -
|===

This cop checks for self-assignments.

=== Examples

[source,ruby]

bad

foo = foo foo, bar = foo, bar Foo = Foo

good

foo = bar foo, bar = bar, foo Foo = Bar

== Lint/SendWithMixinArgument

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.75
| -
|===

This cop checks for `send`, `public_send`, and `__send__` methods
when using mix-in.

`include` and `prepend` methods were private methods until Ruby 2.0,
they were mixed-in via `send` method. This cop uses Ruby 2.1 or
higher style that can be called by public methods.
And `extend` method that was originally a public method is also targeted
for style unification.

=== Examples

[source,ruby]

bad

Foo.send(:include, Bar) Foo.send(:prepend, Bar) Foo.send(:extend, Bar)

bad

Foo.public_send(:include, Bar) Foo.public_send(:prepend, Bar) Foo.public_send(:extend, Bar)

bad

Foo.send(:include, Bar) Foo.send(:prepend, Bar) Foo.send(:extend, Bar)

good

Foo.include Bar Foo.prepend Bar Foo.extend Bar

== Lint/ShadowedArgument

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.52
| -
|===

This cop checks for shadowed arguments.

This cop has `IgnoreImplicitReferences` configuration option.
It means argument shadowing is used in order to pass parameters
to zero arity `super` when `IgnoreImplicitReferences` is `true`.

=== Examples

[source,ruby]

bad

do_something do |foo| foo = 42 puts foo end

def do_something(foo) foo = 42 puts foo end

good

do_something do |foo| foo = foo + 42 puts foo end

def do_something(foo) foo = foo + 42 puts foo end

def do_something(foo) puts foo end

==== IgnoreImplicitReferences: false (default)

[source,ruby]

bad

def do_something(foo) foo = 42 super end

def do_something(foo) foo = super bar end

==== IgnoreImplicitReferences: true

[source,ruby]

good

def do_something(foo) foo = 42 super end

def do_something(foo) foo = super bar end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| IgnoreImplicitReferences
| `false`
| Boolean
|===

== Lint/ShadowedException

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.41
| -
|===

This cop checks for a rescued exception that get shadowed by a
less specific exception being rescued before a more specific
exception is rescued.

=== Examples

[source,ruby]

bad

begin something rescue Exception handle_exception rescue StandardError handle_standard_error end

good

begin something rescue StandardError handle_standard_error rescue Exception handle_exception end

good, however depending on runtime environment.

# # This is a special case for system call errors. # System dependent error code depends on runtime environment. # For example, whether Errno::EAGAIN and Errno::EWOULDBLOCK are # the same error code or different error code depends on environment. # This good case is for Errno::EAGAIN and Errno::EWOULDBLOCK with # the same error code. begin something rescue Errno::EAGAIN, Errno::EWOULDBLOCK handle_standard_error end

== Lint/ShadowingOuterLocalVariable

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.9
| -
|===

This cop checks for the use of local variable names from an outer scope
in block arguments or block-local variables. This mirrors the warning
given by `ruby -cw` prior to Ruby 2.6:
"shadowing outer local variable - foo".

NOTE: Shadowing of variables in block passed to `Ractor.new` is allowed
because `Ractor` should not access outer variables.
eg. following syle is encouraged:

  worker_id, pipe = env
  Ractor.new(worker_id, pipe) do |worker_id, pipe|
  end

=== Examples

[source,ruby]

bad

def some_method foo = 1

  2.times do |foo| # shadowing outer `foo`
    do_something(foo)
  end
end
[source,ruby]

good

def some_method foo = 1

  2.times do |bar|
    do_something(bar)
  end
end
== Lint/StructNewOverride

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.81
| -
|===

This cop checks unexpected overrides of the `Struct` built-in methods
via `Struct.new`.

=== Examples

[source,ruby]

bad

Bad = Struct.new(:members, :clone, :count) b = Bad.new([], true, 1) b.members #⇒ [] (overriding Struct#members) b.clone #⇒ true (overriding Object#clone) b.count #⇒ 1 (overriding Enumerable#count)

good

Good = Struct.new(:id, :name) g = Good.new(1, "foo") g.members #⇒ [:id, :name] g.clone #⇒ #<struct Good id=1, name="foo"> g.count #⇒ 2

== Lint/SuppressedException

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.9
| 0.81
|===

This cop checks for `rescue` blocks with no body.

=== Examples

[source,ruby]

bad

def some_method do_something rescue end

bad

begin do_something rescue end

good

def some_method do_something rescue handle_exception end

good

begin do_something rescue handle_exception end

==== AllowComments: true (default)

[source,ruby]

good

def some_method do_something rescue # do nothing end

good

begin do_something rescue # do nothing end

==== AllowComments: false

[source,ruby]

bad

def some_method do_something rescue # do nothing end

bad

begin do_something rescue # do nothing end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowComments
| `true`
| Boolean
|===

=== References

* https://rubystyle.guide#dont-hide-exceptions

== Lint/SymbolConversion

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| Yes
| 1.9
| -
|===

This cop checks for uses of literal strings converted to
a symbol where a literal symbol could be used instead.

=== Examples

[source,ruby]

bad

'string'.to_sym :symbol.to_sym 'underscored_string'.to_sym :'underscored_symbol' 'hyphenated-string'.to_sym

good

:string :symbol :underscored_string :underscored_symbol :'hyphenated-string'

== Lint/Syntax

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.9
| -
|===

This cop repacks Parser's diagnostics/errors
into RuboCop's offenses.

== Lint/ToEnumArguments

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| No
| 1.1
| -
|===

This cop ensures that `to_enum`/`enum_for`, called for the current method,
has correct arguments.

=== Examples

[source,ruby]

bad

def foo(x, y = 1) return to_enum(callee, x) # y is missing end

good

def foo(x, y = 1) return to_enum(callee, x, y) # alternatives to callee are method and :foo end

== Lint/ToJSON

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.66
| -
|===

This cop checks to make sure `#to_json` includes an optional argument.
When overriding `#to_json`, callers may invoke JSON
generation via `JSON.generate(your_obj)`.  Since `JSON#generate` allows
for an optional argument, your method should too.

=== Examples

[source,ruby]

class Point attr_reader :x, :y

# bad, incorrect arity
def to_json
  JSON.generate([x, y])
end
# good, preserving args
def to_json(*args)
  JSON.generate([x, y], *args)
end
  # good, discarding args
  def to_json(*_args)
    JSON.generate([x, y])
  end
end
== Lint/TopLevelReturnWithArgument

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.89
| -
|===

This cop checks for top level return with arguments. If there is a
top-level return statement with an argument, then the argument is
always ignored. This is detected automatically since Ruby 2.7.

=== Examples

[source,ruby]

Detected since Ruby 2.7

return 1 # 1 is always ignored.

== Lint/TrailingCommaInAttributeDeclaration

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.90
| -
|===

This cop checks for trailing commas in attribute declarations, such as
`#attr_reader`. Leaving a trailing comma will nullify the next method
definition by overriding it with a getter method.

=== Examples

[source,ruby]

bad

class Foo attr_reader :foo,

  def bar
    puts "Unreachable."
  end
end

good

class Foo attr_reader :foo

  def bar
    puts "No problem!"
  end
end
== Lint/TripleQuotes

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| Yes
| 1.9
| -
|===

This cop checks for "triple quotes" (strings delimted by any odd number
of quotes greater than 1).

Ruby allows multiple strings to be implicitly concatenated by just
being adjacent in a statement (ie. `"foo""bar" == "foobar"`). This sometimes
gives the impression that there is something special about triple quotes, but
in fact it is just extra unnecessary quotes and produces the same string. Each
pair of quotes produces an additional concatenated empty string, so the result
is still only the "actual" string within the delimiters.

NOTE: Although this cop is called triple quotes, the same behavior is present
for strings delimited by 5, 7, etc. quotation marks.

=== Examples

[source,ruby]

bad

""" A string """

bad


  A string
'''

good

" A string "

good

<<STRING A string STRING

good (but not the same spacing as the bad case)

'A string'

== Lint/UnderscorePrefixedVariableName

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.21
| -
|===

This cop checks for underscore-prefixed variables that are actually
used.

Since block keyword arguments cannot be arbitrarily named at call
sites, the `AllowKeywordBlockArguments` will allow use of underscore-
prefixed block keyword arguments.

=== Examples

==== AllowKeywordBlockArguments: false (default)

[source,ruby]

bad

[1, 2, 3].each do |_num| do_something(_num) end

query(:sales) do |_id:, revenue:, cost:| {_id: _id, profit: revenue - cost} end

good

[1, 2, 3].each do |num| do_something(num) end

[1, 2, 3].each do |_num| do_something # not using _num end

==== AllowKeywordBlockArguments: true

[source,ruby]

good

query(:sales) do |_id:, revenue:, cost:| {_id: _id, profit: revenue - cost} end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowKeywordBlockArguments
| `false`
| Boolean
|===

== Lint/UnexpectedBlockArity

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| No
| No
| 1.5
| -
|===

This cop checks for a block that is known to need more positional
block arguments than are given (by default this is configured for
`Enumerable` methods needing 2 arguments). Optional arguments are allowed,
although they don't generally make sense as the default value will
be used. Blocks that have no receiver, or take splatted arguments
(ie. `*args`) are always accepted.

Keyword arguments (including `**kwargs`) do not get counted towards
this, as they are not used by the methods in question.

NOTE: This cop matches for method names only and hence cannot tell apart
methods with same name in different classes.

Method names and their expected arity can be configured like this:

Methods:
  inject: 2
  reduce: 2

=== Examples

[source,ruby]

bad

values.reduce {} values.min { |a| a } values.sort { |a; b| a + b }

good

values.reduce { |memo, obj| memo << obj } values.min { |a, b| a <⇒ b } values.sort { |*x| x[0] <⇒ x[1] }

=== Configurable attributes

|===
| Name | Default value | Configurable values

| Methods
| `{"chunk_while"=>2, "each_with_index"=>2, "each_with_object"=>2, "inject"=>2, "max"=>2, "min"=>2, "minmax"=>2, "reduce"=>2, "slice_when"=>2, "sort"=>2}`
|
|===

== Lint/UnifiedInteger

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.43
| -
|===

This cop checks for using Fixnum or Bignum constant.

=== Examples

[source,ruby]

bad

1.is_a?(Fixnum) 1.is_a?(Bignum)

[source,ruby]

good

1.is_a?(Integer)

== Lint/UnmodifiedReduceAccumulator

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| No
| 1.1
| 1.5
|===

Looks for `reduce` or `inject` blocks where the value returned (implicitly or
explicitly) does not include the accumulator. A block is considered valid as
long as at least one return value includes the accumulator.

If the accumulator is not included in the return value, then the entire
block will just return a transformation of the last element value, and
could be rewritten as such without a loop.

Also catches instances where an index of the accumulator is returned, as
this may change the type of object being retained.

NOTE: For the purpose of reducing false positives, this cop only flags
returns in `reduce` blocks where the element is the only variable in
the expression (since we will not be able to tell what other variables
relate to via static analysis).

=== Examples

[source,ruby]

bad

(1..4).reduce(0) do |acc, el| el * 2 end

bad, may raise a NoMethodError after the first iteration

%w(a b c).reduce({}) do |acc, letter| acc[letter] = true end

good

(1..4).reduce(0) do |acc, el| acc + el * 2 end

good, element is returned but modified using the accumulator

values.reduce do |acc, el| el << acc el end

good, returns the accumulator instead of the index

%w(a b c).reduce({}) do |acc, letter| acc[letter] = true acc end

good, at least one branch returns the accumulator

values.reduce(nil) do |result, value| break result if something? value end

good, recursive

keys.reduce(self) { |result, key| result[key] }

ignored as the return value cannot be determined

enum.reduce do |acc, el| x = foo(acc, el) bar(x) end

== Lint/UnreachableCode

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.9
| -
|===

This cop checks for unreachable code.
The check are based on the presence of flow of control
statement in non-final position in `begin` (implicit) blocks.

=== Examples

[source,ruby]

bad

def some_method return do_something end

bad

def some_method if cond return else return end do_something end

[source,ruby]

good

def some_method do_something end

== Lint/UnreachableLoop

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.89
| 1.7
|===

This cop checks for loops that will have at most one iteration.

A loop that can never reach the second iteration is a possible error in the code.
In rare cases where only one iteration (or at most one iteration) is intended behavior,
the code should be refactored to use `if` conditionals.

NOTE: Block methods that are used with `Enumerable`s are considered to be loops.

`IgnoredPatterns` can be used to match against the block receiver in order to allow
code that would otherwise be registered as an offense (eg. `times` used not in an
`Enumerable` context).

=== Examples

[source,ruby]

bad

while node do_something(node) node = node.parent break end

good

while node do_something(node) node = node.parent end

bad

def verify_list(head) item = head begin if verify(item) return true else return false end end while(item) end

good

def verify_list(head) item = head begin if verify(item) item = item.next else return false end end while(item)

  true
end

bad

def find_something(items) items.each do |item| if something?(item) return item else raise NotFoundError end end end

good

def find_something(items) items.each do |item| if something?(item) return item end end raise NotFoundError end

bad

2.times { raise ArgumentError }

==== IgnoredPatterns: [/(exactly|at_least|at_most)\(\d+\)\.times/] (default)

[source,ruby]

good

exactly(2).times { raise StandardError }

=== Configurable attributes

|===
| Name | Default value | Configurable values

| IgnoredPatterns
| `(?-mix:(exactly|at_least|at_most)\(\d+\)\.times)`
| Array
|===

== Lint/UnusedBlockArgument

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.21
| 0.22
|===

This cop checks for unused block arguments.

=== Examples

[source,ruby]

bad

do_something do |used, unused| puts used end

do_something do |bar| puts :foo end

define_method(:foo) do |bar| puts :baz end

good

do_something do |used, _unused| puts used end

do_something do puts :foo end

define_method(:foo) do |_bar| puts :baz end

==== IgnoreEmptyBlocks: true (default)

[source,ruby]

good

do_something { |unused| }

==== IgnoreEmptyBlocks: false

[source,ruby]

bad

do_something { |unused| }

==== AllowUnusedKeywordArguments: false (default)

[source,ruby]

bad

do_something do |unused: 42| foo end

==== AllowUnusedKeywordArguments: true

[source,ruby]

good

do_something do |unused: 42| foo end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| IgnoreEmptyBlocks
| `true`
| Boolean

| AllowUnusedKeywordArguments
| `false`
| Boolean
|===

=== References

* https://rubystyle.guide#underscore-unused-vars

== Lint/UnusedMethodArgument

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.21
| 0.81
|===

This cop checks for unused method arguments.

=== Examples

[source,ruby]

bad

def some_method(used, unused, _unused_but_allowed) puts used end

good

def some_method(used, _unused, _unused_but_allowed) puts used end

==== AllowUnusedKeywordArguments: false (default)

[source,ruby]

bad

def do_something(used, unused: 42) used end

==== AllowUnusedKeywordArguments: true

[source,ruby]

good

def do_something(used, unused: 42) used end

==== IgnoreEmptyMethods: true (default)

[source,ruby]

good

def do_something(unused) end

==== IgnoreEmptyMethods: false

[source,ruby]

bad

def do_something(unused) end

==== IgnoreNotImplementedMethods: true (default)

[source,ruby]

good

def do_something(unused) raise NotImplementedError end

def do_something_else(unused) fail "TODO" end

==== IgnoreNotImplementedMethods: false

[source,ruby]

bad

def do_something(unused) raise NotImplementedError end

def do_something_else(unused) fail "TODO" end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowUnusedKeywordArguments
| `false`
| Boolean

| IgnoreEmptyMethods
| `true`
| Boolean

| IgnoreNotImplementedMethods
| `true`
| Boolean
|===

=== References

* https://rubystyle.guide#underscore-unused-vars

== Lint/UriEscapeUnescape

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.50
| -
|===

This cop identifies places where `URI.escape` can be replaced by
`CGI.escape`, `URI.encode_www_form`, or `URI.encode_www_form_component`
depending on your specific use case.
Also this cop identifies places where `URI.unescape` can be replaced by
`CGI.unescape`, `URI.decode_www_form`,
or `URI.decode_www_form_component` depending on your specific use case.

=== Examples

[source,ruby]

bad

URI.escape('http://example.com') URI.encode('http://example.com')

good

CGI.escape('http://example.com') URI.encode_www_form([['example', 'param'], ['lang', 'en']]) URI.encode_www_form(page: 10, locale: 'en') URI.encode_www_form_component('http://example.com')

bad

URI.unescape(enc_uri) URI.decode(enc_uri)

good

CGI.unescape(enc_uri) URI.decode_www_form(enc_uri) URI.decode_www_form_component(enc_uri)

== Lint/UriRegexp

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.50
| -
|===

This cop identifies places where `URI.regexp` is obsolete and should
not be used. Instead, use `URI::DEFAULT_PARSER.make_regexp`.

=== Examples

[source,ruby]

bad

URI.regexp('http://example.com')

good

URI::DEFAULT_PARSER.make_regexp('http://example.com')

== Lint/UselessAccessModifier

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 0.20
| 0.83
|===

This cop checks for redundant access modifiers, including those with no
code, those which are repeated, and leading `public` modifiers in a
class or module body. Conditionally-defined methods are considered as
always being defined, and thus access modifiers guarding such methods
are not redundant.

This cop has `ContextCreatingMethods` option. The default setting value
is an empty array that means no method is specified.
This setting is an array of methods which, when called, are known to
create its own context in the module's current access context.

It also has `MethodCreatingMethods` option. The default setting value
is an empty array that means no method is specified.
This setting is an array of methods which, when called, are known to
create other methods in the module's current access context.

=== Examples

[source,ruby]

bad

class Foo public # this is redundant (default access is public)

  def method
  end
end

bad

class Foo # The following is redundant (methods defined on the class' # singleton class are not affected by the public modifier) public

  def self.method3
  end
end

bad

class Foo protected

define_method(:method2) do
end
protected # this is redundant (repeated from previous modifier)
  [1,2,3].each do |i|
    define_method("foo#{i}") do
    end
  end
end

bad

class Foo private # this is redundant (no following methods are defined) end

good

class Foo private # this is not redundant (a method is defined)

  def method2
  end
end

good

class Foo # The following is not redundant (conditionally defined methods are # considered as always defining a method) private

  if condition?
    def method
    end
  end
end

good

class Foo protected # this is not redundant (a method is defined)

  define_method(:method2) do
  end
end
==== ContextCreatingMethods: concerning

[source,ruby]

Lint/UselessAccessModifier:

ContextCreatingMethods:

- concerning

good

require 'active_support/concern' class Foo concerning :Bar do def some_public_method end

private
  def some_private_method
  end
end
# this is not redundant because `concerning` created its own context
private
  def some_other_private_method
  end
end
==== MethodCreatingMethods: delegate

[source,ruby]

Lint/UselessAccessModifier:

MethodCreatingMethods:

- delegate

good

require 'active_support/core_ext/module/delegation' class Foo # this is not redundant because delegate creates methods private

  delegate :method_a, to: :method_b
end
=== Configurable attributes

|===
| Name | Default value | Configurable values

| ContextCreatingMethods
| `[]`
| Array

| MethodCreatingMethods
| `[]`
| Array
|===

== Lint/UselessAssignment

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.11
| -
|===

This cop checks for every useless assignment to local variable in every
scope.
The basic idea for this cop was from the warning of `ruby -cw`:

  assigned but unused variable - foo

Currently this cop has advanced logic that detects unreferenced
reassignments and properly handles varied cases such as branch, loop,
rescue, ensure, etc.

=== Examples

[source,ruby]

bad

def some_method some_var = 1 do_something end

[source,ruby]

good

def some_method some_var = 1 do_something(some_var) end

=== References

* https://rubystyle.guide#underscore-unused-vars

== Lint/UselessElseWithoutRescue

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.17
| -
|===

This cop checks for useless `else` in `begin..end` without `rescue`.

NOTE: This syntax is no longer valid on Ruby 2.6 or higher and
this cop is going to be removed at some point the future.

=== Examples

[source,ruby]

bad

begin do_something else do_something_else # This will never be run. end

[source,ruby]

good

begin do_something rescue handle_errors else do_something_else end

== Lint/UselessMethodDefinition

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.90
| -
|===

This cop checks for useless method definitions, specifically: empty constructors
and methods just delegating to `super`.

This cop is marked as unsafe as it can trigger false positives for cases when
an empty constructor just overrides the parent constructor, which is bad anyway.

=== Examples

[source,ruby]

bad

def initialize super end

def method super end

good - with default arguments

def initialize(x = Object.new) super end

good

def initialize super initialize_internals end

def method(*args) super(:extra_arg, *args) end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowComments
| `true`
| Boolean
|===

== Lint/UselessSetterCall

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.13
| 1.2
|===

This cop checks for setter call to local variable as the final
expression of a function definition.
Its auto-correction is marked as unsafe because return value will be changed.

NOTE: There are edge cases in which the local variable references a
value that is also accessible outside the local scope. This is not
detected by the cop, and it can yield a false positive.

=== Examples

[source,ruby]

bad

def something x = Something.new x.attr = 5 end

[source,ruby]

good

def something x = Something.new x.attr = 5 x end

== Lint/UselessTimes

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| No
| Yes (Unsafe)
| 0.91
| -
|===

This cop checks for uses of `Integer#times` that will never yield
(when the integer <= 0) or that will only ever yield once
(`1.times`).

This cop is marked as unsafe as `times` returns its receiver, which
is *usually* OK, but might change behavior.

=== Examples

[source,ruby]

bad

-5.times { do_something } 0.times { do_something } 1.times { do_something } 1.times { |i| do_something(i) }

good

do_something do_something(1)

== Lint/Void

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| No
| 0.9
| -
|===

This cop checks for operators, variables, literals, and nonmutating
methods used in void context.

=== Examples

==== CheckForMethodsWithNoSideEffects: false (default)

[source,ruby]

bad

def some_method some_num * 10 do_something end

def some_method(some_var) some_var do_something end

==== CheckForMethodsWithNoSideEffects: true

[source,ruby]

bad

def some_method(some_array) some_array.sort do_something(some_array) end

good

def some_method do_something some_num * 10 end

def some_method(some_var) do_something some_var end

def some_method(some_array) some_array.sort! do_something(some_array) end

=== Configurable attributes

|===
| Name | Default value | Configurable values

| CheckForMethodsWithNoSideEffects
| `false`
| Boolean
|===