样式

Style/AccessModifierDeclarations

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.57

0.81

访问修饰符应声明为应用于一组方法,或者根据配置在每个方法之前内联。EnforcedStyle 配置仅涵盖方法定义。可以使用 AllowModifiersOnSymbols 配置控制可见性方法对符号的应用。此外,可以使用 AllowModifiersOnAttrs 配置控制 attr* 方法的可见性。

在 Ruby 3.0 中,attr* 方法现在返回一个包含定义的方法名称的符号数组。因此,我们可以以内联方式编写修饰符和 attr*。AllowModifiersOnAttrs 配置允许以内联方式编写 attr* 方法,而无需修改长期以组样式维护的应用程序。此外,不熟悉 Ruby 的开发人员可能知道修饰符适用于 def,但他们可能不知道它也适用于 attr* 方法。如果我们可以以内联方式编写 attr* 方法,则更容易理解。

安全

自动更正不安全,因为动态定义的方法的可见性可能会根据组访问修饰符确定的状态而有所不同。

示例

EnforcedStyle: group(默认)

# 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 (默认)

# good
class Foo

  private :bar, :baz

end

AllowModifiersOnSymbols: false

# bad
class Foo

  private :bar, :baz

end

AllowModifiersOnAttrs: true (默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

group

inline, group

AllowModifiersOnSymbols

true

布尔值

AllowModifiersOnAttrs

true

布尔值

Style/AccessorGrouping

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.87

-

检查 classmodule 代码块中访问器的分组。默认情况下,它强制访问器放置在分组声明中,但可以配置为强制将它们分开在多个声明中。

如果在访问器方法之前有方法调用,则始终允许,因为它可能是像 Sorbet 这样的意图。

示例

EnforcedStyle: grouped (默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

grouped

separated, grouped

Style/Alias

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.36

根据配置强制使用 #alias#alias_method。它还会标记 alias :symbol 的使用,而不是 alias bareword

但是,在实例方法定义和单例方法定义中使用 alias 时,它将始终强制执行 method_alias。如果在块中使用,则始终强制执行 alias_method,除非它是 instance_eval 块。

示例

EnforcedStyle: prefer_alias (默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

prefer_alias

prefer_alias, prefer_alias_method

Style/AndOr

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.9

1.21

检查 andor 的使用,并建议使用 &&|| 代替。它可以配置为仅在条件中或在所有上下文中检查。

安全

自动更正不安全,因为逻辑运算符 (&&||) 和语义运算符 (andor) 之间存在不同的运算符优先级,这可能会改变行为。

示例

EnforcedStyle: conditionals (默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

条件语句

always, conditionals

Style/ArgumentsForwarding

所需 Ruby 版本:2.7
默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.1

1.58

在 Ruby 2.7 中,添加了参数转发功能。

此代码检查器识别可以将 do_something(*args, &block) 替换为 do_something(…​) 的位置。

在 Ruby 3.1 中,添加了匿名块转发功能。

此代码检查器识别可以将 do_something(&block) 替换为 do_something(&) 的位置;如果需要,可以通过设置 UseAnonymousForwarding: false 来禁用此功能。

在 Ruby 3.2 中,添加了匿名参数/关键字参数转发功能。

此代码检查器还识别可以将 use_args(args)/use_kwargs(kwargs) 替换为 use_args()/use_kwargs() 的位置;如果需要,可以通过设置 UseAnonymousForwarding: false 来禁用此功能。

此外,此代码检查器具有 RedundantRestArgumentNamesRedundantKeywordRestArgumentNamesRedundantBlockArgumentNames 选项。此配置是一个冗余名称列表,这些名称足以匿名化无意义的命名。

通常使用的无意义名称可以默认匿名化:例如,args*options&block 等。

默认情况下,不在此列表中的名称很可能是有效的,因此允许使用。

此代码检查器不仅处理方法转发,还处理转发到 super

示例

# 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(默认,仅适用于 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(仅适用于 Ruby >= 3.2)

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

AllowOnlyRestArgument: true(默认,仅适用于 Ruby < 3.2)

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

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

AllowOnlyRestArgument: false(仅适用于 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'](默认)

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

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

冗余关键字剩余参数名称:['kwargs', 'options', 'opts'](默认)

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

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

冗余块参数名称:['blk', 'block', 'proc'](默认)

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

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

可配置属性

名称 默认值 可配置值

AllowOnlyRestArgument

true

布尔值

UseAnonymousForwarding

true

布尔值

RedundantRestArgumentNames

args, arguments

数组

RedundantKeywordRestArgumentNames

kwargs, options, opts

数组

RedundantBlockArgumentNames

blk, block, proc

数组

Style/ArrayCoercion

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

0.88

-

强制使用 Array() 而不是显式 Array 检查或 [*var]

由于安全问题,此 cop 默认情况下已禁用。

安全

此 cop 不安全,因为如果 Array() 的参数为(或可能为)nil,或者取决于 Array() 如何处理参数(这可能与仅将参数包装在数组中不同),则可能会出现误报。

例如

[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"]

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

1.58

-

识别 arr[0]arr[-1] 的用法,并建议将其更改为使用 arr.firstarr.last

由于安全问题,此 cop 默认情况下已禁用。

安全

此 cop 不安全,因为 [0][-1] 可以调用 Hash,它返回 0-1 键的值,但将其更改为使用 .first.last 将返回第一个/最后一个元组。此外,String 并未实现 first/last 方法。

示例

# bad
arr[0]
arr[-1]

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

参考

  • #first-and-last

Style/ArrayIntersect

必需的 Ruby 版本:3.1
默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.40

-

在 Ruby 3.1 中,添加了 Array#intersect?

此 cop 识别 (array1 & array2).any? 可以替换为 array1.intersect?(array2) 的地方。

array1.intersect?(array2) 方法比 (array1 & array2).any? 更快,并且更易读。

在以下情况下,无法确保兼容性,因此在使用块参数时不会检测到它。

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

安全

此 cop 无法保证 array1array2 实际上是数组,而 intersect? 方法仅适用于数组。

示例

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

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

AllCops:ActiveSupportExtensionsEnabled: false(默认)

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.20

0.31

检查使用 "*" 作为 join 的替代品。

由于 Ruby 的动态类型,并非所有情况都能可靠地检查,因此我们只考虑第一个参数是数组字面量或第二个参数是字符串字面量的情况。

示例

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

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

Style/AsciiComments

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.9

1.21

检查注释中是否存在非 ASCII(非英语)字符。您可以在 AllowedChars 属性中设置允许的非 ASCII 字符数组(默认情况下为版权声明 "©")。

示例

# bad
# Translates from English to 日本語。

# good
# Translates from English to Japanese

可配置属性

名称 默认值 可配置值

AllowedChars

©

数组

Style/Attr

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.12

检查 Module#attr 的使用情况。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.30

-

检查您是否可以使用接受块的自动资源清理方法版本的情况。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.25

-

检查 %() 或 %Q() 的使用是否符合配置。

示例

EnforcedStyle: bare_percent(默认)

# 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'/

可配置属性

名称 默认值 可配置值

EnforcedStyle

bare_percent

percent_qbare_percent

Style/BeginBlock

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.9

-

检查 BEGIN 代码块。

示例

# bad
BEGIN { test }

Style/BisectedAttrAccessor

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.87

-

检查同一个方法的 attr_readerattr_writer 是否可以合并成单个 attr_accessor

示例

# bad
class Foo
  attr_reader :bar
  attr_writer :bar
end

# good
class Foo
  attr_accessor :bar
end

Style/BlockComments

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.23

查找块注释 (=begin…​=end) 的使用。

示例

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

# good
# Multiple lines
# of comments...

Style/BlockDelimiters

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.30

0.35

检查单行或多行代码块周围使用大括号或 do/end。

无法从其用法单独分类的既可以是过程式也可以是函数式的函数将被忽略。lambdaprocit 是它们的默认值。可以将其他方法添加到 AllowedMethods 中。

示例

EnforcedStyle: line_count_based (默认)

# 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' ] (默认)

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

foo = lambda do |x|
  x * 100
end

AllowedPatterns: [] (默认)

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

AllowedPatterns: ['map']

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

可配置属性

名称 默认值 可配置值

EnforcedStyle

line_count_based

line_count_basedsemanticbraces_for_chainingalways_braces

ProceduralMethods

benchmarkbmbmbmcreateeach_with_objectmeasurenewrealtimetapwith_object

数组

FunctionalMethods

letlet!subjectwatch

数组

AllowedMethods

lambdaprocit

数组

AllowedPatterns

[]

数组

AllowBracesOnProceduralOneLiners

false

布尔值

BracesRequiredMethods

[]

数组

Style/CaseEquality

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.89

如果启用了 AllowOnSelfClass 选项,该 cop 将忽略当 case 等式运算符的接收者为 self.class 时的违规行为。注意,中间变量不被接受。

示例

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

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

AllowOnConstant: false(默认)

# bad
Array === something

AllowOnConstant: true

# good
Array === something

AllowOnSelfClass: false(默认)

# bad
self.class === something

AllowOnSelfClass: true

# good
self.class === something

可配置属性

名称 默认值 可配置值

AllowOnConstant

false

布尔值

AllowOnSelfClass

false

布尔值

Style/CaseLikeIf

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.88

1.48

识别 if-elsif 结构可以被 case-when 替换的地方。

安全性

此 cop 不安全。case 语句使用 === 进行相等性比较,因此如果原始条件使用不同的相等性运算符,则行为可能会有所不同。

示例

MinBranchesCount: 3(默认)

# 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

可配置属性

名称 默认值 可配置值

MinBranchesCount

3

整数

Style/CharacterLiteral

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

-

检查对字符字面量 ?x 的使用。从 Ruby 1.9 开始,字符字面量本质上是一字符字符串,因此这种语法在此时大多是多余的。

? 字符字面量可用于表示元字符和控制字符。这是 ? 字面量的一个很好的用例,因此它不会将其视为违规。

示例

# bad
?x

# good
'x'

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

Style/ClassAndModuleChildren

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.19

-

检查类和模块中子定义的样式。基本上有两种不同的样式

紧凑样式仅强制用于只有一个子元素的类/模块。

安全性

自动更正不安全。

从紧凑样式移动到嵌套子元素需要了解外部父元素是模块还是类。从嵌套样式移动到紧凑样式需要验证外部父元素是否在其他地方定义。RuboCop 没有执行任何操作所需的知识,因此需要人工监督。

示例

EnforcedStyle: nested(默认)

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

强制风格:紧凑

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

可配置属性

名称 默认值 可配置值

EnforcedStyle

嵌套

嵌套紧凑

Style/ClassCheck

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.24

-

强制一致使用Object#is_a?Object#kind_of?

示例

强制风格:is_a?(默认)

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

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

强制风格:kind_of?

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

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

可配置属性

名称 默认值 可配置值

EnforcedStyle

is_a?

is_a?kind_of?

Style/ClassEqualityComparison

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.93

1.57

强制使用Object#instance_of?而不是类比较来判断相等性。默认情况下允许==equal?eql?自定义方法定义。这些可以通过AllowedMethods选项进行自定义。

安全性

此 cop 的自动更正不安全,因为在将var.class.name == 'Foo'自动更正为var.instance_of?(Foo)时,无法保证常量Foo存在。

示例

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

# good
var.instance_of?(Date)

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

# 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:[](默认)

# 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

可配置属性

名称 默认值 可配置值

AllowedMethods

==equal?eql?

数组

AllowedPatterns

[]

数组

Style/ClassMethods

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.20

检查在定义类/模块方法时是否使用类/模块名称而不是self。

示例

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

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

Style/ClassMethodsDefinitions

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.89

-

强制使用def self.method_nameclass << self来定义类方法。

示例

强制风格:def_self(默认)

# 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

强制风格:self_class

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

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

可配置属性

名称 默认值 可配置值

EnforcedStyle

def_self

def_selfself_class

Style/ClassVars

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.13

-

检查类变量的使用。 只有在对类变量赋值时才会发出违规信号,以减少报告的违规数量。

在设置类变量的值时要小心; 如果一个类被继承,更改类变量的值也会影响继承类。 这意味着几乎总是最好使用类实例变量。

示例

# 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

所需 Ruby 版本:2.4
默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.2

1.3

检查从数组和哈希中拒绝 nil 的自定义逻辑可以被替换为 {Array,Hash}#{compact,compact!} 的地方。

安全

默认情况下它是不安全的,因为在接收对象块参数的 nil 检查中可能会出现误报。 此外,我们无法确定接收对象的类型,这也会导致误报。

例如,[[1, 2], [3, nil]].reject { |first, second| second.nil? }[[1, 2], [3, nil]].compact 不兼容。 当接收者是哈希对象时,这将正常工作。

示例

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

# good
array.compact

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

# good
hash.compact!

AllowedReceivers: ['params']

# good
params.reject(&:nil?)

可配置属性

名称 默认值 可配置值

AllowedReceivers

[]

数组

Style/CollectionMethods

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

0.9

1.7

强制使用 Enumerable 模块中一致的方法名。

您可以自定义从不希望使用的方法到希望使用的方法的映射。

例如,使用 detect 代替 find

Style/CollectionMethods:
  PreferredMethods:
    find: detect

安全

这个 cop 不安全,因为它通过名称查找方法,而实际上无法确定接收者是否为 Enumerable,因此这个 cop 可能会注册误报。

示例

# 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?

可配置属性

名称 默认值 可配置值

PreferredMethods

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

MethodsAcceptingSymbol

inject, reduce

数组

Style/ColonMethodCall

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

-

检查使用 :: 运算符而不是 . 运算符调用的方法(例如 FileUtils::rmdir 而不是 FileUtils.rmdir)。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.52

-

检查使用 :: 运算符而不是 . 运算符定义的类方法。

示例

# bad
class Foo
  def self::bar
  end
end

# good
class Foo
  def self.bar
  end
end

Style/CombinableLoops

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.90

-

检查多个连续循环遍历相同数据的地方是否可以合并为单个循环。合并它们很可能使代码更高效和更简洁。

安全

该 cop 不安全,因为第一个循环可能会修改第二个循环依赖的状态;这两个循环不可合并。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.30

-

强制在命令字面量周围使用 `` 或 %x。

示例

EnforcedStyle: backticks(默认)

# 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(默认)

# 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\``

可配置属性

名称 默认值 可配置值

EnforcedStyle

backticks

backtickspercent_xmixed

AllowInnerBackticks

false

布尔值

Style/CommentAnnotation

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.10

1.20

检查注释标注关键字是否符合指南。

可以通过覆盖 cop 的 Keywords 配置来指定标注关键字。关键字可以是单个单词或短语。

对于多行注释块(其中每一行都只是一个注释),只有第一行才能注册违规,即使标注关键字在另一行开始。这样做是为了防止在段落中错误地注册关键字(例如 review)作为标注。

示例

RequireColon: true (默认)

# 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

可配置属性

名称 默认值 可配置值

关键字

TODO, FIXME, OPTIMIZE, HACK, REVIEW, NOTE

数组

RequireColon

true

布尔值

Style/CommentedKeyword

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.51

1.19

检查与某些关键字位于同一行的注释。这些关键字是:class, module, def, begin, end

请注意,某些注释(:nodoc:, :yields:, rubocop:disablerubocop:todo)是允许的。

自动更正会从 end 关键字中删除注释,并将 class, module, defbegin 的注释保留在关键字上方。

安全性

自动更正不安全,因为它可能会删除有意义的注释。

示例

# 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

所需 Ruby 版本:2.4
默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.44

-

强制使用 Comparable#clamp 而不是通过最小值和最大值进行比较。

此 cop 支持仅针对 if/elsif/else 不良风格的自动更正。因为如果 clamp 参数的最小值和最大值颠倒,则会发生 ArgumentError。当这些是变量时,无法确定哪个是最小值和最大值

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

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.41

-

强制使用 Array#push(item) 而不是 Array#concat([item]) 来避免冗余的数组字面量。

安全性

此 cop 不安全,因为它如果接收者不是 Array 对象,可能会产生误报。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.36

0.47

检查 ifcase 语句,其中每个分支都用于同一个变量的赋值和比较,而使用条件的返回值可以代替。

示例

EnforcedStyle: assign_to_condition (默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

assign_to_condition

assign_to_condition, assign_inside_condition

SingleLineConditionsOnly

true

布尔值

IncludeTernaryExpressions

true

布尔值

Style/ConstantVisibility

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.66

1.10

检查类和模块中定义的常量是否具有显式的可见性声明。默认情况下,Ruby 使所有类和模块常量都公开,这会使类或模块的公共 API 混乱。显式声明可见性可以使意图更加清晰,并防止外部参与者触碰私有状态。

示例

# bad
class Foo
  BAR = 42
  BAZ = 43
end

# good
class Foo
  BAR = 42
  private_constant :BAR

  BAZ = 43
  public_constant :BAZ
end

IgnoreModules: false(默认)

# 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

可配置属性

名称 默认值 可配置值

IgnoreModules

false

布尔值

Style/Copyright

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.30

-

检查每个源文件中是否提供了版权声明。

可以在 config/default.yml 中找到可接受版权声明的默认正则表达式。默认值可以按如下方式更改

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

此正则表达式字符串被视为未锚定的正则表达式。对于 RuboCop 扫描的每个文件,必须找到与该正则表达式匹配的注释,否则会报告违规。

可配置属性

名称 默认值 可配置值

Notice

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

String

AutocorrectNotice

``

String

Style/DataInheritance

必需的 Ruby 版本:3.2
默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.49

1.51

检查是否从 Data.define 继承以避免创建匿名父类。

安全性

自动更正不安全,因为它会更改常量的继承树(例如 Module#ancestors 的返回值)。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

0.51

0.92

检查是否一致地使用 DateTime 类而不是 Time 类。此 cop 默认情况下处于禁用状态,因为这些类虽然高度重叠,但具有特殊性,在处理多个时区和/或 DST 时,在某些情况下无法替换它们。

安全性

自动更正不安全,因为 DateTimeTime 的行为并不完全相同,尽管在大多数情况下自动更正会很好。

示例

# 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(默认)

# bad - coerces to `DateTime`
something.to_datetime

# good - coerces to `Time`
something.to_time

AllowCoercion: true

# good
something.to_datetime

# good
something.to_time

可配置属性

名称 默认值 可配置值

AllowCoercion

false

布尔值

Style/DefWithParentheses

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.12

检查不带参数的方法定义中是否有括号。 同时检查实例方法和类/单例方法。

示例

# 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

所需 Ruby 版本:2.0
默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.50

-

检查可以使用 #_\_dir\_\_ 方法替换更复杂结构以检索当前文件的规范化绝对路径的地方。

示例

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

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

# good
path = __dir__

Style/DirEmpty

所需 Ruby 版本:2.4
默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.48

-

在检查目录是否为空时,建议使用 Dir.empty?('path/to/dir')

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.82

1.9

检测用于启用/禁用 RuboCop 的注释。 这在您希望确保每个 RuboCop 错误都被修复,而不是通过注释快速禁用时很有用。

可以使用 AllowedCops 配置允许特定的代码检查器。 请注意,如果设置了此配置,则 rubocop:disable all 仍然不允许。

示例

# 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

可配置属性

名称 默认值 可配置值

AllowedCops

[]

数组

Style/DocumentDynamicEvalDefinition

默认启用 安全 支持自动更正 添加版本 更改版本

待定

1.1

1.3

当使用 class_eval(或其他 eval)进行字符串插值时,添加一个注释块,显示其插值后的外观(Rails 代码中使用的做法)。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.9

-

检查类和模块的顶级文档是否缺失。 没有主体类的检查将被免除,命名空间模块也是如此 - 模块中除了类、其他模块、常量定义或常量可见性声明之外什么都没有。

如果类或模块旁边有 :nodoc: 注释,则文档要求将被取消。 同样,:nodoc: all 对其所有子项执行相同的操作。

示例

# 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

可配置属性

名称 默认值 可配置值

AllowedConstants

[]

数组

Exclude

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

数组

Style/DocumentationMethod

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.43

-

检查公共方法是否缺少文档注释。它可以可选地配置为也要求非公共方法的文档。

此 cop 允许 initialize 方法,因为 initialize 是从 new 调用的特殊方法。在某些编程语言中,它们被称为构造函数,以将其与方法区分开来。

示例

# 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(默认)

# 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

可配置属性

名称 默认值 可配置值

AllowedMethods

[]

数组

Exclude

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

数组

RequireForNonPublicMethods

false

布尔值

Style/DoubleCopDisableDirective

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.73

-

检测一行上的双重禁用注释。这主要是为了捕获需要重新生成的自动生成的注释。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.19

1.2

检查使用双重否定(!!)将某些内容转换为布尔值的情况。

当使用 EnforcedStyle: allowed_in_returns 时,允许在使用布尔值作为返回值的上下文中使用双重否定。当使用 EnforcedStyle: forbidden 时,应始终禁止双重否定。

something 是一个布尔值时,!!something!something.nil? 并不相同。由于您不太可能编写可以接受任何类型值的代码,因此在实践中这很少是一个问题。

安全

当值为 false 时,自动更正是不安全的,因为表达式的结果将发生变化。

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

示例

# bad
!!something

# good
!something.nil?

EnforcedStyle: allowed_in_returns(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

allowed_in_returns

allowed_in_returns, forbidden

Style/EachForSimpleLoop

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.41

-

检查使用范围文字和 #each 迭代固定次数的循环。这可以使用 Integer#times 更清晰地完成。

此检查仅在代码块不接受参数时适用。

示例

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

# good
5.times { }
# bad
(0...10).each {}

# good
10.times {}

Style/EachWithObject

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.22

0.42

查找 inject / reduce 调用,其中传入的对象在最后被返回,因此可以使用 each_with_object 替换,而无需在最后返回对象。

但是,如果累加器参数在代码块内被赋值,则不能用 each_with_object 替换。

示例

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

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

Style/EmptyBlockParameter

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.52

-

检查空代码块参数的管道。空代码块参数的管道不会导致语法错误,但它们是多余的。

示例

# bad
a do ||
  do_something
end

# bad
a { || do_something }

# good
a do
end

# good
a { do_something }

Style/EmptyCaseCondition

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.40

-

检查具有空条件的 case 语句。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

仅命令行

0.28

1.61

检查空 else 子句,可能包括注释和/或显式 nil,具体取决于 EnforcedStyle。

示例

EnforcedStyle: both(默认)

# 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(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

both

emptynilboth

AllowComments

false

布尔值

Style/EmptyHeredoc

默认启用 安全 支持自动更正 添加版本 更改版本

待定

仅命令行

1.32

1.61

检查使用空 heredoc 来减少冗余。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.52

-

检查空 lambda 参数的括号。空 lambda 参数的括号不会导致语法错误,但它们是多余的。

示例

# bad
-> () { do_something }

# good
-> { do_something }

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

Style/EmptyLiteral

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.12

检查使用方法,该方法的结果将是文字,例如空数组、哈希或字符串。

示例

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

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

Style/EmptyMethod

默认启用 安全 支持自动更正 添加版本 更改版本

启用

仅命令行

0.46

1.61

检查空方法定义的格式。默认情况下,它强制空方法定义在一行上(紧凑样式),但可以配置为强制end在它自己的行上(扩展样式)。

如果方法定义包含注释,则不认为它是空的。
如果生成的代码比Layout/LineLengthMax配置更长,则不会对compact样式应用自动更正,但仍会注册违规。

示例

EnforcedStyle: compact(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

compact

compact, expanded

Style/Encoding

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.50

检查确保源文件没有 utf-8 编码注释。

示例

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

Style/EndBlock

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.81

检查 END 块。

示例

# bad
END { puts 'Goodbye!' }

# good
at_exit { puts 'Goodbye!' }

Style/EndlessMethod

必需的 Ruby 版本:3.0
默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.8

-

检查无穷方法。

它可以强制执行对单行方法体使用无穷方法定义,或者禁止无穷方法。

此 cop 不考虑其他方法定义类型。

支持的样式是

  • allow_single_line(默认) - 仅允许单行无穷方法定义。

  • allow_always - 允许所有无穷方法定义。

  • disallow - 禁止所有无穷方法定义。

不正确的无穷方法定义将始终被更正为多行定义。

示例

EnforcedStyle: allow_single_line(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

允许单行

allow_single_lineallow_alwaysdisallow

Style/EnvHome

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.29

-

检查 ENV['HOME'] 的一致使用。如果 nil 用作 ENV.fetch 的第二个参数,则将其视为与 ENV[] 相似的错误情况。

安全

该 cop 不安全,因为当 nil 被分配给 ENV['HOME'] 时,结果会发生变化

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

示例

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

# good
Dir.home

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

Style/EvalWithLocation

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.52

-

确保 eval 方法(evalinstance_evalclass_evalmodule_eval)被赋予文件名和行号值(_\_FILE\__\__LINE\_\_)。这些数据用于确保在评估代码中引发的任何错误都将在回溯中获得正确的标识。

该 cop 还检查相对于 _\_LINE\_\_ 给出的行号是否正确。

该 cop 将自动更正不正确或缺少的文件名和行号值。但是,如果 eval 在没有绑定参数的情况下被调用,则该 cop 不会尝试自动添加绑定,也不会添加文件名和行值。

该 cop 仅在字符串文字作为代码字符串给出时才有效。如果字符串变量如下给出,则不会报告任何违规

示例

# 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
# not checked
code = <<-RUBY
  def do_something
  end
RUBY
eval code

Style/EvenOdd

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.12

0.29

检查可以使用 Integer#even?Integer#odd? 的地方。

示例

# bad
if x % 2 == 0
end

# good
if x.even?
end

Style/ExactRegexpMatch

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.51

-

检查正则表达式文字内部的精确正则表达式匹配。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.53

-

检查 File.expand_path 参数的使用情况。同样,它还检查 Pathname.new 参数。

以下示例交替显示对比的错误情况和正确情况。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.89

1.8

强制使用显式块参数,避免编写仅将参数传递给另一个块的块字面量。

此 cop 仅在块参数与 yield 参数完全匹配时才注册违规。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.82

-

强制在代码中使用指数表示法表示数字(例如 1.2e4)时保持一致性。支持不同的样式

  • scientific 强制尾数在 1(包含)和 10(不包含)之间。

  • engineering 强制指数为 3 的倍数,尾数在 0.1(包含)和 10(不包含)之间。

  • integral 强制尾数始终为整数,没有尾随零。

示例

EnforcedStyle: scientific(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

scientific

scientificengineeringintegral

Style/FetchEnvVar

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.28

-

建议使用 ENV.fetch 替换 ENV[]ENV[] 在环境变量未设置时会静默失败并返回 nil,这可能会导致开发人员忘记设置环境变量时出现意外行为。另一方面,ENV.fetch 会引发 KeyError 或返回显式指定的默认值。

示例

# 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?`)

可配置属性

名称 默认值 可配置值

AllowedVars

[]

数组

Style/FileEmpty

所需 Ruby 版本:2.4
默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.48

-

在检查文件是否为空时,建议使用 File.empty?('path/to/file')

安全

此 cop 不安全,因为 File.sizeFile.readFile.binread 在没有与路径对应的文件时会引发 ENOENT 异常,而 File.empty? 不会引发异常。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.24

-

优先使用 File.(bin)read 方便方法。

示例

## text mode
# bad
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)
## binary mode
# bad
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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.24

-

建议使用 File.(bin)write 方便方法。

File.write(类方法)和 File#write(实例方法)之间存在不同的方法签名。以下情况将被允许,因为静态分析不知道 splat 参数的内容
File.open(filename, 'w') do |f|
  f.write(*objects)
end

示例

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

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

# good
File.binwrite(filename, content)

Style/FloatDivision

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.72

1.9

检查将整数强制转换为浮点数的除法。建议始终使用 fdiv 或只强制转换一侧。此 cop 还提供其他选项以确保代码一致性。

安全

此 cop 不安全,因为如果操作数变量是字符串对象,则 .to_f 将被删除,并且会发生错误。

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

示例

EnforcedStyle: single_coerce(默认)

# 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)

可配置属性

名称 默认值 可配置值

EnforcedStyle

single_coerce

left_coerceright_coercesingle_coercefdiv

Style/For

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.13

1.26

查找使用 for 关键字或 each 方法的地方。首选的替代方案在 EnforcedStyle 配置参数中设置。单行上的带有块的 each 调用始终被允许。

安全

此 cop 的自动更正不安全,因为变量的作用域在 eachfor 之间不同。

示例

EnforcedStyle: each(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

each

eachfor

Style/FormatString

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.19

0.49

强制使用单个字符串格式化实用程序。有效选项包括 Kernel#formatKernel#sprintfString#%

无法以可靠的方式对所有情况下的 String#% 进行检测,因此只考虑两种情况 - 如果第一个参数是字符串文字,以及如果第二个参数是数组文字。

当使用参数是文字或已知的内置转换方法(如 to_dto_fto_hto_ito_rto_sto_sym)在变量上时,将应用自动更正,前提是它们的返回值不是数组。例如,当使用 to_s 时,'%s' % [1, 2, 3].to_s 可以自动更正,不会有任何不兼容性

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

示例

EnforcedStyle: format(默认)

# 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'

可配置属性

名称 默认值 可配置值

EnforcedStyle

format

format, sprintf, percent

Style/FormatStringToken

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.49

1.0

使用一致的样式命名格式字符串标记。

unannotated 样式检查器仅适用于作为参数传递给以下方法的字符串:printfsprintfformat%。原因是unannotated 格式与编码的 URL 或日期/时间格式字符串非常相似。

此检查器可以使用 AllowedMethods 自定义允许的方法。默认情况下,没有允许的方法。

如果未注释标记的数量小于或等于 MaxUnannotatedPlaceholdersAllowed,则允许包含未注释标记。

示例

EnforcedStyle: annotated(默认)

# 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(默认)

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

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

AllowedMethods: [](默认)

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

AllowedMethods: [redirect]

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

AllowedPatterns: [](默认)

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

AllowedPatterns: ['redirect']

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

可配置属性

名称 默认值 可配置值

EnforcedStyle

annotated

annotated, template, unannotated

MaxUnannotatedPlaceholdersAllowed

1

整数

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

Style/FrozenStringLiteralComment

所需 Ruby 版本:2.3
默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.36

0.79

帮助您从可变字符串字面量过渡到冻结字符串字面量。它将在文件的顶部添加 # frozen_string_literal: true 魔法注释以启用冻结字符串字面量。冻结字符串字面量在未来的 Ruby 中可能是默认的。该注释将添加到 shebang 和编码注释下方。冻结字符串字面量注释仅在 Ruby 2.3+ 中有效。

请注意,检查器将接受存在注释但设置为 false 而不是 true 的文件。

要在此注释后要求空行,请参阅 Layout/EmptyLineAfterMagicComment 检查器。

安全

此代码的自动更正不安全,因为任何字符串的变异都会从被接受变为引发FrozenError,因为默认情况下所有字符串都将被冻结,需要手动重构。

示例

EnforcedStyle: always(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

always

always, always_true, never

Style/GlobalStdStream

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.89

-

强制使用$stdout/$stderr/$stdin而不是STDOUT/STDERR/STDINSTDOUT/STDERR/STDIN是常量,虽然你实际上可以在 Ruby 中重新分配常量(可能用于重定向某些流),但如果你这样做,你会得到解释器的警告。

安全性

自动更正不安全,因为例如STDOUT$stdout可能指向不同的对象。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.13

-

查找全局变量的使用。它不会报告内置全局变量的违规。默认情况下允许内置全局变量。此外,用户可以通过AllowedVariables选项允许其他变量。

请注意,像 $1、$2 等等这样的反向引用不是全局变量。

示例

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

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

可配置属性

名称 默认值 可配置值

AllowedVariables

[]

数组

Style/GuardClause

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.20

1.31

使用保护子句而不是将代码包装在条件表达式中

除非在条件表达式的正文中使用了returnbreaknextraisefail,否则允许带有elsifelse分支的条件。

自动更正适用于大多数情况,除了包含逻辑运算符(如foo || raise('exception'))的 if-else 语句。

示例

# 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 (默认)

# 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

可配置属性

名称 默认值 可配置值

MinBodyLength

1

整数

AllowConsecutiveConditionals

false

布尔值

Style/HashAsLastArrayItem

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.88

-

根据配置检查哈希字面量作为最后一个数组项时是否包含大括号。

此 cop 将忽略所有项都是哈希的数组,无论 EnforcedStyle 如何。

示例

EnforcedStyle: braces (默认)

# 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 }]

可配置属性

名称 默认值 可配置值

EnforcedStyle

braces

braces, no_braces

Style/HashConversion

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.10

1.55

检查 2.1 之前的 Hash[args] 方法将可枚举和值序列转换为哈希的使用情况。

从 splat 参数 (Hash[*ary]) 的更正代码并非简单确定。例如,Hash[*ary] 可以替换为 ary.each_slice(2).to_h,但这将很复杂。因此,AllowSplatArgument 选项默认情况下为 true,以允许对简单代码使用 splat 参数。

安全

此 cop 的自动更正不安全,因为如果元素数量为奇数,则会发生 ArgumentError

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

示例

# bad
Hash[ary]

# good
ary.to_h

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

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

AllowSplatArgument: true (默认)

# good
Hash[*ary]

AllowSplatArgument: false

# bad
Hash[*ary]

可配置属性

名称 默认值 可配置值

AllowSplatArgument

true

布尔值

Style/HashEachMethods

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.80

1.16

检查 each_keyeach_value 哈希方法的使用情况。

如果您有一个包含两个元素数组的数组,您可以将括号放在块参数周围以指示您不是在使用哈希,并抑制 RuboCop 违规。

安全

此 cop 不安全,因为它无法保证接收者是 HashAllowedReceivers 配置可以减轻,但不能完全解决此安全问题。

示例

# 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 }

可配置属性

名称 默认值 可配置值

AllowedReceivers

Thread.current

数组

Style/HashExcept

必需的 Ruby 版本:3.0
默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.7

1.39

检查使用 Hash#rejectHash#selectHash#filter 方法的情况,这些方法可以用 Hash#except 方法替换。

此 cop 应该只在 Ruby 版本 3.0 或更高版本上启用。(Hash#except 在 Ruby 3.0 中添加。)

为了安全检测,它仅限于在使用 == 时常用的字符串和符号比较。并且不要检查 Hash#delete_ifHash#keep_if 来更改接收器对象。

安全性

此 cop 不安全,因为它无法保证接收器是 Hash 或响应替换方法。

示例

# 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[foo bar].include?(k) }
{foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[foo bar].include?(k) }
{foo: 1, bar: 2, baz: 3}.filter {|k, v| !%i[foo bar].include?(k) }

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

Style/HashLikeCase

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.88

-

检查 case-when 代表简单的 1:1 映射并且可以用哈希查找替换的地方。

示例

MinBranchesCount: 3(默认)

# 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

可配置属性

名称 默认值 可配置值

MinBranchesCount

3

整数

Style/HashSyntax

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

1.24

检查哈希文字语法。

它可以强制使用类哈希火箭语法或使用更新的 Ruby 1.9 语法(如果适用)。

每个有问题的对都会注册一个单独的违规。

支持的样式是

  • ruby19 - 强制使用 1.9 语法(例如 {a: 1}),当哈希的所有键都是符号时

  • hash_rockets - 强制对所有哈希使用哈希火箭

  • no_mixed_keys - 只检查具有混合语法的哈希

  • ruby19_no_mixed_keys - 强制使用 ruby 1.9 语法并禁止混合语法哈希

此 cop 有 EnforcedShorthandSyntax 选项。它可以强制使用显式哈希值语法或使用 Ruby 3.1 的哈希值简写语法。

支持的样式是

  • always - 强制使用 3.1 语法(例如 {foo:})

  • never - 强制使用显式哈希文字值

  • either - 接受简写和显式使用哈希文字值

  • consistent - 仅当所有值都可以在哈希中省略时才强制使用 3.1 语法

  • either_consistent - 接受简写和显式使用哈希文字值,但它们必须一致

示例

强制风格:ruby19(默认)

# 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

强制风格:hash_rockets

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

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

强制风格:no_mixed_keys

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

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

强制风格: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}

强制简写语法:always(默认)

# bad
{foo: foo, bar: bar}

# good
{foo:, bar:}

强制简写语法:never

# bad
{foo:, bar:}

# good
{foo: foo, bar: bar}

强制简写语法:either

# good
{foo: foo, bar: bar}

# good
{foo: foo, bar:}

# good
{foo:, bar:}

强制简写语法: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}

强制简写语法: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}

可配置属性

名称 默认值 可配置值

EnforcedStyle

ruby19

ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys

EnforcedShorthandSyntax

always

always, never, either, consistent, either_consistent

UseHashRocketsWithSymbolValues

false

布尔值

PreferHashRocketsForNonAlnumEndingSymbols

false

布尔值

Style/HashTransformKeys

所需 Ruby 版本:2.5
默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.80

0.90

查找使用 _.each_with_object({}) {…​}, \_.map {…​}.to_hHash[\_.map {…​}] 实际上只是转换哈希键的情况,并尝试使用更简单且更快的 transform_keys 调用来代替。它应该只在 Ruby 版本 2.5 或更高版本上启用。(transform_keys 在 Ruby 2.5 中添加。)

安全性

此 cop 不安全,因为它可能会产生误报,如果我们正在转换不是哈希的键值对枚举,例如:[[k1, v1], [k2, v2], …​]

示例

# 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

所需 Ruby 版本:2.4
默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.80

0.90

查找使用 _.each_with_object({}) {…​}, \_.map {…​}.to_hHash[\_.map {…​}] 实际上只是转换哈希值的情况,并尝试使用更简单且更快的 transform_values 调用来代替。

安全性

此 cop 不安全,因为它可能会产生误报,如果我们正在转换不是哈希的键值对枚举,例如:[[k1, v1], [k2, v2], …​]

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.36

1.19

检查条件表达式每个分支开头或结尾处的相同表达式。此类表达式通常应放置在条件表达式之外 - 在其之前或之后。

此 cop 的命名不当,有些人可能会认为它实际上检查的是重复的条件分支。该名称可能会在未来的主要 RuboCop 版本中更改。

安全性

自动更正不安全,因为更改方法调用的顺序可能会改变代码的行为。例如

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

在此示例中,method_that_relies_on_global_state 将被移到 method_that_modifies_global_state 之前,这会改变程序的行为。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.36

1.3

如果条件语句的 else 分支仅包含一个 if 节点,则可以将其与 else 合并为 elsif。这有助于防止嵌套级别过深。

示例

# 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(默认)

# 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

可配置属性

名称 默认值 可配置值

AllowIfModifier

false

布尔值

Style/IfUnlessModifier

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.30

检查可以作为修饰符 if/unless 写在一行上的 ifunless 语句。该 cop 还检查超过最大行长的修饰符 if/unless 行。

最大行长在 Layout/LineLength cop 中配置。制表符大小在 Layout/IndentationStyle cop 的 IndentationWidth 中配置。

始终允许单行模式匹配。为了确保很少有匹配变量未使用的案例,并防止疏忽。当以下示例更改为修饰符形式时,变量 x 将变为未定义并引发 NameError

if [42] in [x]
  x # `x` is undefined when using modifier form.
end
defined? 参数具有未定义的值时,这是允许的,因为使用修饰符形式会导致以下不兼容
unless defined?(undefined_foo)
  undefined_foo = 'default_value'
end
undefined_foo # => 'default_value'

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

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.39

0.87

检查用作其他 if 或 unless 语句的修饰符的 if 和 unless 语句。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.9

-

检查具有布尔文字分支的冗余 if。它仅检查返回布尔值(truefalse)的条件,以进行安全检测。要检查的条件是比较方法、谓词方法和双重否定(!!)。默认情况下允许 nonzero? 方法。这些可以通过 AllowedMethods 选项自定义。

此 cop 仅针对具有单个 elsifelse 分支的 if。以下代码将被允许,因为它有两个 elsif 分支

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

安全

自动更正是不安全的,因为无法保证所有谓词方法都会返回布尔值。可以使用 AllowedMethods 配置允许这些方法。

示例

# 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?'](默认)

# good
num.nonzero? ? true : false

可配置属性

名称 默认值 可配置值

AllowedMethods

nonzero?

数组

Style/IfWithSemicolon

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.83

检查 if 语句中是否使用分号。

示例

# bad
result = if some_condition; something else another_thing end

# good
result = some_condition ? something : another_thing

Style/ImplicitRuntimeError

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.41

-

检查未指定显式异常类的 raisefail 语句。(这会引发 RuntimeError。一些项目可能更喜欢使用更精确地标识错误性质的异常类。)

示例

# bad
raise 'Error message here'

# good
raise ArgumentError, 'Error message here'

Style/InPatternThen

所需 Ruby 版本:2.7
默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.16

-

检查 case 表达式中是否使用 in;

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.26

0.61

对于无限循环,请使用 Kernel#loop

安全

此 cop 不安全,因为如果循环体可能会引发 StopIteration 异常,则规则不应强制执行;与其他无限循环相反,Kernel#loop 会静默地捕获该异常并返回 nil

示例

# bad
while true
  work
end

# good
loop do
  work
end

Style/InlineComment

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.23

-

检查尾随内联注释。

示例

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

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

Style/InverseMethods

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.48

-

检查在方法上调用 not(not!)的情况,在这种情况下可以使用该方法的逆方法。

可以通过 not(not!)反转的方法应在 InverseMethods 中定义。

通过反转传递给方法的块的返回值来反转的方法应在 InverseBlocks 中定义。

安全

此 cop 不安全,因为无法保证该方法及其逆方法都定义在接收器上,并且实际上是彼此的逆方法。

示例

# 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

可配置属性

名称 默认值 可配置值

逆方法

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

逆块

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

Style/InvertibleUnlessCondition

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

1.44

1.50

检查使用unless的情况,这些情况可以用if和反转的条件来替换。没有unless的代码更容易阅读,但这只是主观的,所以这个cop默认情况下是禁用的。

可以反转的方法应该在InverseMethods中定义。注意,逆方法的关系需要在两个方向上定义。例如,

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

将建议同时反转even?odd?,但只反转!=(而不是==)。

安全

此 cop 不安全,因为无法保证该方法及其逆方法都定义在接收器上,并且实际上是彼此的逆方法。

示例

# 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

可配置属性

名称 默认值 可配置值

逆方法

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

Style/IpAddresses

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.58

0.91

检查硬编码的IP地址,这会导致代码变得脆弱。IP地址很可能需要在代码部署到不同的服务器或环境时进行更改,如果忘记更改,可能会导致部署失败。建议在ENV或其他配置中设置IP地址。

示例

# bad
ip_address = '127.59.241.29'

# good
ip_address = ENV['DEPLOYMENT_IP_ADDRESS']

可配置属性

名称 默认值 可配置值

AllowedAddresses

::

数组

Exclude

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

数组

Style/KeywordParametersOrder

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.90

1.7

强制将可选关键字参数放在参数列表的末尾。

这提高了可读性,因为在查看源代码时,预计在参数列表的开头找到必需参数,在结尾找到可选参数。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.40

(默认情况下)检查单行lambda使用lambda字面量语法,多行lambda使用方法调用语法。它可以配置为对单行和多行lambda强制执行其中一种样式。

示例

EnforcedStyle: line_count_dependent(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

line_count_dependent

line_count_dependentlambdaliteral

Style/LambdaCall

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.13

0.14

检查是否使用 lambda.(args) 语法。

示例

EnforcedStyle: call(默认)

# bad
lambda.(x, y)

# good
lambda.call(x, y)

EnforcedStyle: braces

# bad
lambda.call(x, y)

# good
lambda.(x, y)

可配置属性

名称 默认值 可配置值

EnforcedStyle

call

callbraces

Style/LineEndConcatenation

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.18

0.64

检查字符串字面量连接是否出现在行尾。

安全

此 cop 不安全,因为无法保证接收者是字符串,在这种情况下,用 \ 替换 << 会导致语法错误。

例如,这将是一个误报

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

示例

# bad
some_str = 'ala' +
           'bala'

some_str = 'ala' <<
           'bala'

# good
some_str = 'ala' \
           'bala'

Style/MagicCommentFormat

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.35

-

确保在整个代码库中一致地编写魔术注释。查找分隔符(-_)和魔术注释指令和值的区分大小写之间的差异。

可以使用 DirectiveCapitalizationValueCapitalization 配置键设置所需的大小写。

如果其中一个配置设置为 nil,则允许任何大小写。

示例

EnforcedStyle: snake_case(默认)

# 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(默认)

# 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(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

snake_case

snake_casekebab_case

DirectiveCapitalization

lowercase

String

ValueCapitalization

<none>

Style/MapCompactWithConditionalBlock

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.30

-

优先使用 selectreject 而不是 map { …​ }.compact

示例

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

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.63

-

检查使用 each<<pushappend 的情况,这些情况可以用 map 替换。

如果在 Style/CollectionMethods 中为 map 配置了 PreferredMethods,则此 cop 使用指定的方法进行替换。

Enumerable#each 的返回值是 self,而 Enumerable#map 的返回值是 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`

安全

此代码不安全,因为并非所有具有 each 方法的对象也具有 map 方法(例如 ENV)。此外,对于带块的调用,并非所有具有 map 方法的对象都返回数组(例如 Enumerator::Lazy)。

示例

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

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

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

Style/MapToHash

所需的 Ruby 版本:2.6
默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.24

-

查找使用 map.to_hcollect.to_h 的情况,这些情况可以在 Ruby >= 2.6 中仅使用 to_h 来编写。

Style/HashTransformKeysStyle/HashTransformValues 也会更改此模式,如果仅转换哈希键或哈希值。

安全

此代码不安全,因为它可能会产生误报,如果接收者不是 Enumerable

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.42

-

查找使用 map.to_setcollect.to_set 的情况,这些情况可以使用 to_set 来编写。

安全

此代码不安全,因为它可能会产生误报,如果接收者不是 Enumerable

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.47

1.7

强制在包含参数的方法调用中使用(默认)或不使用括号。

在默认样式(require_parentheses)中,允许使用宏方法。可以将其他方法添加到 AllowedMethodsAllowedPatterns 列表中。这些选项仅在默认样式中有效。可以通过将 IgnoreMacros 设置为 false 或将特定宏添加到 IncludedMacros 列表中来包含宏。

选项的优先级如下

  1. AllowedMethods

  2. AllowedPatterns

  3. IncludedMacros

如果一个方法同时出现在 IncludedMacrosAllowedMethods 中,则后者优先(即,该方法是允许的)。

在备用样式(omit_parentheses)中,还有三个额外的选项。

  1. AllowParenthesesInChaining 默认情况下为 false。将其设置为 true 允许在方法链中的最后一个调用中使用括号。

  2. AllowParenthesesInMultilineCall 默认值为 false。将其设置为 true 允许在多行方法调用中使用括号。

  3. AllowParenthesesInCamelCaseMethod 默认值为 false。这允许在调用名称以大写字母开头且没有参数的方法时使用括号。将其设置为 true 允许在这样的方法调用中使用括号,即使有参数。

omit_parentheses 样式允许在省略括号会导致代码歧义或语法错误的情况下使用括号。

非详尽的示例列表

  • 在带有参数的方法调用中,括号是必需的,允许在字面量、逻辑运算符、设置位置和关键字参数的默认值、链式调用等情况下使用括号。

  • 在带有参数的方法调用中,允许在运算符内使用括号以避免歧义。Ruby 2.7 中引入的三点语法,因为省略它们会启动一个无限范围。

  • 在使用 Ruby 2.7 中引入的三点语法转发参数时,允许使用括号,因为省略它们会启动一个无限范围。

  • 在 Ruby 3.0 中引入的无限方法定义中,在带有参数的调用中需要使用括号。

  • Ruby 3.1 的哈希省略语法允许在方法调用位于条件语句中时使用括号,如果调用不是返回值表达式,则需要使用括号。参见 https://bugs.ruby-lang.org/issues/18396

  • 在 Ruby 3.2 中,匿名参数、关键字参数和块传递中需要使用括号。

示例

强制样式:require_parentheses(默认)

# 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

强制样式: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

忽略宏:true(默认)

# good
class Foo
  bar :baz
end

忽略宏:false

# bad
class Foo
  bar :baz
end

AllowParenthesesInMultilineCall:false(默认)

# bad
foo.enforce(
  strict: true
)

# good
foo.enforce \
  strict: true

AllowParenthesesInMultilineCall:true

# good
foo.enforce(
  strict: true
)

# good
foo.enforce \
  strict: true

AllowParenthesesInChaining:false(默认)

# bad
foo().bar(1)

# good
foo().bar 1

AllowParenthesesInChaining:true

# good
foo().bar(1)

# good
foo().bar 1

AllowParenthesesInCamelCaseMethod:false(默认)

# bad
Array(1)

# good
Array 1

AllowParenthesesInCamelCaseMethod:true

# good
Array(1)

# good
Array 1

AllowParenthesesInStringInterpolation:false(默认)

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

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

AllowParenthesesInStringInterpolation:true

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

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

可配置属性

名称 默认值 可配置值

忽略宏

true

布尔值

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

IncludedMacros

[]

数组

AllowParenthesesInMultilineCall

false

布尔值

AllowParenthesesInChaining

false

布尔值

AllowParenthesesInCamelCaseMethod

false

布尔值

AllowParenthesesInStringInterpolation

false

布尔值

EnforcedStyle

require_parentheses

require_parenthesesomit_parentheses

Style/MethodCallWithoutArgsParentheses

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.47

0.55

检查无参数方法调用中不必要的括号。

此检查器可以使用 AllowedMethods 自定义允许的方法。默认情况下,没有允许的方法。

此 cop 允许在块中使用无参数的 it(),例如 0.times { it() },遵循 Lint/ItWithoutArgumentsInBlock cop。

示例

# bad
object.some_method()

# good
object.some_method

AllowedMethods: [] (默认)

# bad
object.foo()

AllowedMethods: [foo]

# good
object.foo()

可配置属性

名称 默认值 可配置值

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

Style/MethodCalledOnDoEndBlock

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.14

-

检查在 do…​end 块上调用的方法。此检查的目的是,在阅读代码时很容易错过附加到块的调用。

示例

# bad
a do
  b
end.c

# good
a { b }.c

# good
foo = a do
  b
end
foo.c

Style/MethodDefParentheses

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.16

1.7

检查方法定义中参数周围的括号。检查实例方法和类/单例方法。

无论样式如何,以下情况都需要括号:

  1. 无限方法

  2. 包含 forward-arg (…​) 的参数列表

  3. 包含匿名剩余参数转发 (*) 的参数列表

  4. 包含匿名关键字剩余参数转发 (**) 的参数列表

  5. 包含匿名块转发 (&) 的参数列表

在此处删除括号将导致语法错误。

示例

EnforcedStyle: require_parentheses (默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

require_parentheses

require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline

Style/MinMax

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.50

-

检查 Enumerable#minmax 的潜在用法。

示例

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

# good
bar = foo.minmax
return foo.minmax

Style/MinMaxComparison

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.42

-

强制使用 maxmin 代替比较运算符来判断大于或小于。

如果您想在 Ruby 2.7+ 中表示限制或阈值,可以使用此规则。但是,这种方法速度较慢。因此,自动更正将应用通用的 maxmin
a.clamp(b..) # Same as `[a, b].max`
a.clamp(..b) # Same as `[a, b].min`

安全

此规则不安全,因为即使一个值具有 <> 方法,它也不一定是 Comparable

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.30

0.38

检查没有 else 分支的 if 表达式。

模式匹配允许没有 else 分支,因为与 ifcase 不同,如果模式不匹配,它会引发 NoMatchingPatternError,而无需 else

支持的样式包括:if、case、both。

示例

EnforcedStyle: both (默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

both

ifcaseboth

Style/MissingRespondToMissing

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.56

-

检查 method_missing 的存在,但不定义 respond_to_missing?

示例

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

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

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

Style/MixinGrouping

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.48

0.49

检查 classmodule 主体中 mixin 的分组。默认情况下,它强制将 mixin 放置在单独的声明中,但可以配置为强制将它们分组在一个声明中。

示例

EnforcedStyle: separated (默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

separated

separated, grouped

Style/MixinUsage

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.51

-

检查 includeextendprepend 语句是否出现在类和模块内部,而不是在顶层,这样就不会影响 Object 的行为。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.11

0.65

检查模块中是否使用extend selfmodule_function

支持的样式有:module_function(默认)、extend_selfforbidden

需要注意以下几点

  • forbidden样式禁止使用这两种样式

  • 在默认模式(module_function)下,如果模块包含任何私有方法,则不会激活该规则

安全性

自动更正是不安全的(默认情况下已禁用),因为extend selfmodule_function的行为并不完全相同。

示例

EnforcedStyle: module_function(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

module_function

module_functionextend_selfforbidden

自动修正

false

布尔值

Style/MultilineBlockChain

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.13

-

检查在跨越多行的另一个块之后是否链接块。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.45

-

检查是否使用带有多行主体的 if/unless 修饰符。

示例

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

# good
{ result: 'ok' } if cond

Style/MultilineIfThen

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.26

检查在多行 if 语句中是否使用then关键字。

示例

# 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

所需 Ruby 版本:2.7
默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.16

-

检查在多行in语句中是否使用then关键字。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.44

0.48

检查用于多行记忆的表达式包装样式。

示例

EnforcedStyle: keyword(默认)

# bad
foo ||= (
  bar
  baz
)

# good
foo ||= begin
  bar
  baz
end

EnforcedStyle: braces

# bad
foo ||= begin
  bar
  baz
end

# good
foo ||= (
  bar
  baz
)

可配置属性

名称 默认值 可配置值

EnforcedStyle

keyword

keywordbraces

Style/MultilineMethodSignature

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.59

1.7

检查跨越多行的函数签名。

示例

# good

def foo(bar, baz)
end

# bad

def foo(bar,
        baz)
end

Style/MultilineTernaryOperator

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.86

检查多行三元运算符表达式。

return if …​ else …​ end 是语法错误。如果在多行三元运算符表达式之前使用 return,它将自动更正为单行三元运算符。对于 breaknext 和方法调用也是如此。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.73

-

检查多行 when 语句中 then 关键字的使用。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.49

1.1

检查将变量与多个项目进行比较的情况,其中可以使用 Array#include?Set#include?case 来避免代码重复。默认情况下,它接受对多个方法调用的比较,以避免不必要的调用。它可以通过 AllowMethodComparison 选项进行配置。

示例

# 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(默认)

# 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(默认)

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

ComparisonsThreshold: 3

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

可配置属性

名称 默认值 可配置值

AllowMethodComparison

true

布尔值

ComparisonsThreshold

2

整数

Style/MutableConstant

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.34

1.8

检查一些常量值是否不是可变字面量(例如数组或哈希)。

严格模式可用于冻结所有常量,而不仅仅是字面量。严格模式被认为是实验性功能。它尚未更新所有将生成冻结对象的完整方法列表,因此有相当大的可能性会产生一些误报。幸运的是,冻结已经冻结的对象不会造成任何伤害。

从 Ruby 3.0 开始,此 cop 遵守魔法注释 'shareable_constant_value'。当此魔法注释设置为除 none 之外的任何可接受值时,它将抑制此 cop 引起的违规。它强制执行冻结状态。

自 Ruby 3.0 以来,Regexp 和 Range 字面量是冻结对象。
从 Ruby 3.0 开始,当使用 # frozen-string-literal: true 时,插值字符串不会被冻结,因此此 cop 对此类字符串强制执行显式冻结。
从 Ruby 3.0 开始,当使用 shareable_constant_value 指令时,此 cop 允许对常量进行显式冻结。

安全

此 cop 的自动更正是不安全的,因为对已冻结对象的任何修改将从被接受变为引发 FrozenError,并且需要手动重构。

示例

EnforcedStyle: literals(默认)

# 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]

可配置属性

名称 默认值 可配置值

EnforcedStyle

literals

literalsstrict

Style/NegatedIf

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.20

0.48

检查使用带否定条件的 if。仅考虑没有 else 的 if。有三种不同的风格

  • both

  • prefix

  • postfix

示例

EnforcedStyle: both(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

both

bothprefixpostfix

Style/NegatedIfElseCondition

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.2

-

检查使用带否定条件的 if-else 和三元运算符,这些条件可以通过反转条件和交换分支来简化。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.69

-

检查使用带否定条件的 unless。仅考虑没有 else 的 unless。有三种不同的风格

  • both

  • prefix

  • postfix

示例

EnforcedStyle: both(默认)

# 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

强制风格:前缀

# enforces `if` for just `prefix` conditionals

# bad
unless !foo
  bar
end

# good
if foo
  bar
end

# good
bar unless !foo

强制风格:后缀

# enforces `if` for just `postfix` conditionals

# bad
bar unless !foo

# good
bar if foo

# good
unless !foo
  bar
end

可配置属性

名称 默认值 可配置值

EnforcedStyle

both

bothprefixpostfix

Style/NegatedWhile

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.20

-

检查使用带否定条件的 while。

示例

# bad
while !foo
  bar
end

# good
until foo
  bar
end

# bad
bar until !foo

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

Style/NestedFileDirname

必需的 Ruby 版本:3.1
默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.26

-

检查嵌套的 File.dirname。它用 Ruby 3.1 中引入的 level 参数替换嵌套的 File.dirname

示例

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

# good
File.dirname(path, 2)

Style/NestedModifier

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.35

-

检查 if、unless、while 和 until 的修饰符形式的嵌套使用。

示例

# bad
something if a if b

# good
something if b && a

Style/NestedParenthesizedCalls

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.36

0.77

检查带括号的方法调用参数列表中的未带括号的方法调用。bebe_abe_anbe_betweenbe_falseybe_kind_ofbe_instance_ofbe_truthybe_withineqeqlend_withincludematchraise_errorrespond_tostart_with 方法默认允许。这些方法可以使用 AllowedMethods 选项进行自定义。

示例

# good
method1(method2(arg))

# bad
method1(method2 arg)

AllowedMethods: [foo]

# good
method1(foo arg)

可配置属性

名称 默认值 可配置值

AllowedMethods

bebe_abe_anbe_betweenbe_falseybe_kind_ofbe_instance_ofbe_truthybe_withineqeqlend_withincludematchraise_errorrespond_tostart_with

数组

Style/NestedTernaryOperator

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.86

检查嵌套的三元运算符表达式。

示例

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

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

Style/Next

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.22

0.35

使用 next 跳过迭代,而不是在末尾使用条件。

示例

强制风格:skip_modifier_ifs(默认)

# 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

强制风格: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

可配置属性

名称 默认值 可配置值

EnforcedStyle

skip_modifier_ifs

skip_modifier_ifsalways

MinBodyLength

3

整数

Style/NilComparison

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.12

0.59

检查使用 ==nil? 与 nil 进行比较。

支持的样式:谓词,比较。

示例

EnforcedStyle: predicate (默认)

# bad
if x == nil
end

# good
if x.nil?
end

EnforcedStyle: comparison

# bad
if x.nil?
end

# good
if x == nil
end

可配置属性

名称 默认值 可配置值

EnforcedStyle

谓词

predicate, comparison

Style/NilLambda

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.3

1.15

检查始终返回 nil 的 lambda 和 proc,这些 lambda 和 proc 可以用空 lambda 或 proc 代替。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.20

0.22

检查非 nil 检查,这些检查通常是多余的。

默认情况下,IncludeSemanticChanges 设置为 false,此 cop 不会报告 !x.nil? 的违规行为,也不会进行可能改变行为的更改。同样,当 IncludeSemanticChanges 设置为 falseStyle/NilComparison cop 的 EnforcedStyle: comparison 时,此 cop 不会报告 x != nil 的违规行为,也不会对 !x.nil? 样式进行更改。

IncludeSemanticChanges 设置为 true 时,此 cop 会报告 !x.nil? 的违规行为,并自动更正 !x.nil?x != nilx,这通常是可以的,但可能会改变行为。

示例

# 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 (默认)

# good
if !x.nil?
end

IncludeSemanticChanges: true

# bad
if !x.nil?
end

可配置属性

名称 默认值 可配置值

IncludeSemanticChanges

false

布尔值

Style/Not

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.20

检查使用关键字 not 而不是 !

示例

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

# good
x = !something

Style/NumberedParameters

所需 Ruby 版本:2.7
默认启用 安全 支持自动更正 添加版本 更改版本

待定

1.22

-

检查编号参数。

它可以限制编号参数的使用范围,仅限于单行块,或者完全禁止编号参数。

示例

EnforcedStyle: allow_single_line (默认)

# 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 }

可配置属性

名称 默认值 可配置值

EnforcedStyle

允许单行

allow_single_line, disallow

Style/NumberedParametersLimit

所需 Ruby 版本:2.7
默认启用 安全 支持自动更正 添加版本 更改版本

待定

1.22

-

检测在一个块中使用过多的编号参数。使用过多的编号参数会导致代码过于隐晦,难以阅读。

此 cop 默认情况下,如果存在超过 1 个编号参数,则会注册违规行为,但此最大值可以通过设置 Max 来配置。

示例

最大值:1(默认)

# 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) }

可配置属性

名称 默认值 可配置值

最大值

1

整数

Style/NumericLiteralPrefix

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.41

-

检查八进制、十六进制、二进制和十进制字面量是否使用大写前缀,并将其更正为小写前缀或无前缀(十进制情况下)。

示例

EnforcedOctalStyle: zero_with_o(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedOctalStyle

zero_with_o

zero_with_o, zero_only

Style/NumericLiterals

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.48

检查大型数字字面量是否在数字组之间使用_

可以通过将正则表达式添加到AllowedPatterns配置中来添加其他允许的模式。所有正则表达式都被视为锚定,即使模式不包含锚定(因此\d{4}_\d{4}将允许1234_5678,但不允许1234_5678_9012)。

即使给出了AllowedPatterns,自动更正也将只更正为每 3 位数字一个_的标准模式。

示例

# bad
1000000
1_00_000
1_0000

# good
1_000_000
1000

Strict: false(默认)

# 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)

可配置属性

名称 默认值 可配置值

MinDigits

5

整数

Strict

false

布尔值

AllowedNumbers

[]

数组

AllowedPatterns

[]

数组

Style/NumericPredicate

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.42

0.59

检查是否使用比较运算符(==><)来测试数字是否为零、正数或负数。这些可以使用它们各自的谓词方法替换。此 cop 也可以配置为执行相反的操作。

此检查器可以使用 AllowedMethods 自定义允许的方法。默认情况下,没有允许的方法。

此 cop 忽略#nonzero?,因为它的值是真值或假值,而不是truefalse,因此并不总是可以与!= 0互换。

此 cop 允许与全局变量进行比较,因为它们通常填充了可以与整数比较的对象,但它们本身不是Integer多态的。

安全

此 cop 不安全,因为无法保证接收者定义了谓词或可以与数字进行比较,这可能会导致非标准类的误报。

示例

EnforcedStyle: predicate(默认)

# 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: [] (默认) 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: [] (默认) 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?

可配置属性

名称 默认值 可配置值

EnforcedStyle

谓词

predicate, comparison

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

Exclude

spec/**/*

数组

Style/ObjectThen

所需的 Ruby 版本:2.6
默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.28

-

强制使用一致的方法名 Object#yield_selfObject#then

示例

EnforcedStyle: then (默认)

# 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 }

可配置属性

名称 默认值 可配置值

EnforcedStyle

then

then, yield_self

Style/OneLineConditional

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.90

检查单行上的 if/then/else/end 结构的使用。AlwaysCorrectToMultiline 配置选项可以设置为 true 以自动将所有违规转换为多行结构。当 AlwaysCorrectToMultiline 为 false(默认情况)时,自动更正将首先尝试将它们转换为三元运算符。

示例

# 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

可配置属性

名称 默认值 可配置值

AlwaysCorrectToMultiline

false

布尔值

Style/OpenStructUse

默认启用 安全 支持自动更正 添加版本 更改版本

待定

1.23

1.51

标记 OpenStruct 的使用,因为它现在正式不鼓励使用,因为存在性能、版本兼容性和潜在的安全问题。

安全

请注意,此 cop 可能会标记误报;例如,以下对手动编写的 OpenStruct 类型的合法使用将被视为违规

module MyNamespace
  class OpenStruct # not the OpenStruct we're looking for
  end

  def new_struct
    OpenStruct.new # resolves to MyNamespace::OpenStruct
  end
end

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.37

-

检查运算符方法调用之前的冗余点。目标运算符方法是|^&<⇒======~>>=<<<>>+-/%*~!!=!~

示例

# bad
foo.+ bar
foo.& bar

# good
foo + bar
foo & bar

Style/OptionHash

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.33

0.34

检查选项哈希,如果当前 Ruby 版本支持关键字参数,则不鼓励使用它们。

示例

# bad
def fry(options = {})
  temperature = options.fetch(:temperature, 300)
  # ...
end

# good
def fry(temperature: 300)
  # ...
end

可配置属性

名称 默认值 可配置值

SuspiciousParamNames

optionsoptsargsparamsparameters

数组

允许列表

[]

数组

Style/OptionalArguments

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.33

0.83

检查方法的可选参数,这些参数不在参数列表的末尾。

安全性

此 cop 不安全,因为更改方法签名将隐式更改行为。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

0.89

-

检查在定义方法时可以使用关键字参数代替布尔参数的地方。默认情况下允许 respond_to_missing? 方法。这些可以通过 AllowedMethods 选项自定义。

安全性

此 cop 不安全,因为更改方法签名将隐式更改行为。

示例

# 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

可配置属性

名称 默认值 可配置值

AllowedMethods

respond_to_missing?

数组

Style/OrAssignment

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.50

-

检查潜在的 ||= 运算符用法。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.32

-

检查并行赋值的简单用法。这只会抱怨当被赋值的变量数量与赋值变量的数量匹配时。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.56

检查 if/unless/while/until 条件中是否存在多余的括号。

AllowSafeAssignment 选项用于安全赋值。安全赋值是指在赋值周围加上括号,表示“我知道我正在使用赋值作为条件,这不是错误”。

示例

# 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(默认)

# good
foo unless (bar = baz)

AllowSafeAssignment: false

# bad
foo unless (bar = baz)

AllowInMultilineConditions: false(默认)

# bad
if (x > 10 &&
   y > 10)
end

# good
 if x > 10 &&
    y > 10
 end

AllowInMultilineConditions: true

# good
if (x > 10 &&
   y > 10)
end

可配置属性

名称 默认值 可配置值

AllowSafeAssignment

true

布尔值

AllowInMultilineConditions

false

布尔值

Style/PercentLiteralDelimiters

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.19

0.48

强制一致使用 %-字面量分隔符。

指定 'default' 键以一次设置所有首选分隔符。您可以继续指定单个首选分隔符以覆盖默认值。

示例

# Style/PercentLiteralDelimiters:
#   PreferredDelimiters:
#     default: '[]'
#     '%i':    '()'

# good
%w[alpha beta] + %i(gamma delta)

# bad
%W(alpha #{beta})

# bad
%I(alpha beta)

可配置属性

名称 默认值 可配置值

PreferredDelimiters

{"default"⇒"()", "%i"⇒"[]", "%I"⇒"[]", "%r"⇒"{}", "%w"⇒"[]", "%W"⇒"[]"}

Style/PercentQLiterals

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.25

-

检查使用 %Q() 语法时是否可以使用 %q()。

示例

EnforcedStyle: lower_case_q(默认)

# 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!'}

可配置属性

名称 默认值 可配置值

EnforcedStyle

lower_case_q

lower_case_q, upper_case_q

Style/PerlBackrefs

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.13

-

查找使用 Perl 风格的正则表达式匹配反向引用及其英文版本,如 $1、$2、$&、&+、$MATCH、$PREMATCH 等。

示例

# bad
puts $1

# good
puts Regexp.last_match(1)

Style/PreferredHashMethods

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.41

0.70

检查使用 Hash#has_key?Hash#has_value? 方法,并建议使用 Hash#key?Hash#value? 代替。

可以使用 EnforcedStyle: verbose 配置来强制执行详细的方法名称。

安全

此 cop 不安全,因为无法保证接收者是 Hash 或响应替换方法。

示例

EnforcedStyle: short (默认)

# 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?

可配置属性

名称 默认值 可配置值

EnforcedStyle

short

short, verbose

Style/Proc

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.18

检查使用 Proc.new 的情况,在 Kernel#proc 更合适的地方。

示例

# bad
p = Proc.new { |n| puts n }

# good
p = proc { |n| puts n }

Style/QuotedSymbols

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.16

-

检查用于引号符号的引号是否与配置的默认值匹配。默认情况下使用与 Style/StringLiterals 相同的配置;如果该 cop 未启用,则默认 EnforcedStylesingle_quotes

字符串插值始终保持在双引号中。

注意:Lint/SymbolConversion 可以与之并行使用,以确保不需要引号的符号没有被引号括起来。此 cop 用于配置对需要引号的符号使用的引号样式。

示例

EnforcedStyle: same_as_string_literals (默认) / single_quotes

# bad
:"abc-def"

# good
:'abc-def'
:"#{str}"
:"a\'b"

EnforcedStyle: double_quotes

# bad
:'abc-def'

# good
:"abc-def"
:"#{str}"
:"a\'b"

可配置属性

名称 默认值 可配置值

EnforcedStyle

same_as_string_literals

same_as_string_literals, single_quotes, double_quotes

Style/RaiseArgs

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.14

1.61

检查传递给 failraise 的参数。对于展开样式(默认),建议将异常类和消息传递给 raise,而不是构造错误实例。它仍然允许只传递消息,或使用多个参数构造错误。

爆炸式风格的工作方式完全相同,但增加了当异常传递多个参数时,它还会建议构建错误对象。

爆炸式风格有一个AllowedCompactTypes配置选项,它接受一个包含异常名称字符串的数组。

安全

这个 cop 不安全,因为raise Foo 调用Foo.exception,而不是Foo.new

示例

EnforcedStyle: exploded(默认)

# 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'

可配置属性

名称 默认值 可配置值

EnforcedStyle

exploded

compact, exploded

AllowedCompactTypes

[]

数组

Style/RandomWithOffset

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.52

-

检查使用随机生成的数字,加上/减去整数字面量,以及使用 Integer#succ 和 Integer#pred 方法的数字。建议使用范围,因为它清楚地说明了意图。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.4

1.55

检查传递给某些方法的冗余参数。

这个 cop 仅限于具有单个参数的方法。

方法名称及其冗余参数可以像这样配置

Methods:
  join: ''
  sum: 0
  split: ' '
  chomp: "\n"
  chomp!: "\n"
  foo: 2

安全

这个 cop 不安全,因为有以下限制

  1. 这个 cop 仅通过方法名称匹配,因此无法区分不同类中具有相同名称的方法。

  2. 如果设置了某些特殊的全局变量(例如$;$/),这个 cop 可能会不安全。当然,这取决于目标方法的性质。例如,join 的默认参数是$OUTPUT_FIELD_SEPARATOR(或$,),而不是'',如果更改了该全局变量,'' 就不是冗余参数了。

示例

# 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

可配置属性

名称 默认值 可配置值

方法

{"join"⇒"", "sum"⇒0, "exit"⇒true, "exit!"⇒false, "split"⇒" ", "chomp"⇒"\n", "chomp!"⇒"\n"}

Style/RedundantArrayConstructor

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.52

-

检查使用冗余Array构造函数实例化数组。自动更正替换为数组字面量,这是最简单和最快的。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.87

-

检查返回之前冗余的赋值。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.10

0.21

检查冗余的begin块。

目前它检查以下代码

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.76

-

检查使用 %W() 语法时,是否可以使用 %w()。

示例

# bad
%W(cat dog pig)
%W[door wall floor]

# good
%w/swim run bike/
%w[shirt pants shoes]
%W(apple #{fruit} grape)

Style/RedundantCondition

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.76

-

检查不必要的条件表达式。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.50

-

检查条件语句中冗余的 true/false 返回值。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.40

-

避免在常量上使用冗余的 :: 前缀。

Ruby 搜索常量的方式有点复杂,从代码中很难理解 :: 是否是故意的。当 Module.nesting 为空时,不需要添加 :: 前缀,因此最好始终避免这种无意义的 :: 前缀,以避免混淆。

如果启用了 Lint/ConstantResolution 规则,则此规则将被禁用,以防止规则冲突。因为它尊重用户配置,这些配置希望启用默认情况下禁用的 Lint/ConstantResolution 规则。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.53

-

检查路径中是否使用了冗余的当前目录。

示例

# bad
require_relative './path/to/feature'

# good
require_relative 'path/to/feature'

Style/RedundantDoubleSplatHashBraces

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.41

-

检查是否冗余地使用了双 splat 哈希括号。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.38

-

检查是否使用了冗余的 each

安全

此规则不安全,因为它可能会产生误报,如果接收者不是 Enumerator

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.14

0.29

检查 raise/fail 的参数是否为 RuntimeError

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.86

-

识别可以将 fetch(key) { value } 替换为 fetch(key, value) 的地方。

在这种情况下,fetch(key, value) 方法比 fetch(key) { value } 方法更快。

当启用冻结字符串文字魔术注释(即 # frozen_string_literal: true)时,会检测到 hash.fetch(:key) { 'value' } 中的块字符串 'value',但在禁用时不会检测到。

安全

此 cop 不安全,因为无法保证接收者没有不同的 fetch 实现。

示例

SafeForConstants: false(默认)

# 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)

可配置属性

名称 默认值 可配置值

SafeForConstants

false

布尔值

Style/RedundantFileExtensionInRequire

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.88

-

检查 requirerequire_relative 提供的文件名中是否存在多余的 .rb 扩展名。

注意:如果省略扩展名,Ruby 会尝试在名称中添加 .rb.so 等,直到找到为止。如果找不到名为的文件,将引发 LoadError。存在一个边缘情况,如果 foo.so 文件存在,则会加载 foo.so 文件而不是 LoadError,当 require 'foo.rb' 将更改为 require 'foo' 时,但这似乎无害。

示例

# bad
require 'foo.rb'
require_relative '../foo.rb'

# good
require 'foo'
require 'foo.so'
require_relative '../foo'
require_relative '../foo.so'

Style/RedundantFilterChain

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.52

1.57

识别 any?empty?none? 谓词方法链接到 select/filter/find_all 的用法,并将它们更改为使用谓词方法。

安全

此 cop 的自动更正不安全,因为 array.select.any? 通过 select 方法评估所有元素,而 array.any? 使用短路评估。换句话说,array.select.any? 保证评估每个元素,但 array.any? 不一定评估所有元素。

示例

# 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(默认)

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.34

0.66

检查对不可变对象使用 Object#freeze 的情况。

自 Ruby 3.0 以来,Regexp 和 Range 字面量是冻结对象。
从 Ruby 3.0 开始,当使用 # frozen-string-literal: true 时,此 cop 允许显式冻结插值字符串字面量。

示例

# bad
CONST = 1.freeze

# good
CONST = 1

Style/RedundantHeredocDelimiterQuotes

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.45

-

检查多行字符串分隔符引号是否冗余。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

仅命令行(不安全)

1.27

1.61

检查冗余的 initialize 方法。

如果初始化器什么也不做,或者只调用 super 并传递与传递给它的参数相同的参数,则初始化器是冗余的。如果初始化器接受一个可以接受多个值的参数(restargkwrestarg 等),则不会注册违规,因为它允许初始化器接受与它的超类可能不同的参数数量。

如果初始化器参数具有默认值,RuboCop 假设它 **不** 是冗余的。
空初始化器被注册为违规,但可以有意创建空 initialize 方法来覆盖超类的初始化器。

安全性

此 cop 不安全,因为如果子类以与超类不同的参数数量覆盖 initialize 方法。

示例

# 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(默认)

# good
def initialize
  # Overriding to negate superclass `initialize` method.
end

AllowComments: false

# bad
def initialize
  # Overriding to negate superclass `initialize` method.
end

可配置属性

名称 默认值 可配置值

AllowComments

true

布尔值

Style/RedundantInterpolation

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.76

1.30

检查仅为插值表达式的字符串。

安全性

自动更正不安全,因为当调用字符串的破坏性方法时,结果字符串可能具有不同的行为或引发 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`.

示例

# bad
"#{@var}"

# good
@var.to_s

# good if @var is already a String
@var

Style/RedundantLineContinuation

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.49

-

检查冗余的行延续。

如果删除反斜杠不会导致语法错误,此 cop 将行延续标记为冗余。但是,注释末尾的反斜杠或用于字符串连接的反斜杠不是冗余的,不被视为违规。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.36

-

检查冗余的括号。

示例

# bad
(x) if ((y.z).nil?)

# good
x if y.z.nil?

Style/RedundantPercentQ

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.76

-

检查使用 %q/%Q 语法时是否可以使用 '' 或 ""。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.53

-

识别可以将参数从确定性正则表达式替换为字符串的地方。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.85

-

检查不必要的单元素正则表达式字符类。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.52

-

检查使用冗余 Regexp.newRegexp.compile 实例化正则表达式。自动更正替换为正则表达式字面量,这是最简单和最快的。

示例

# bad
Regexp.new(/regexp/)
Regexp.compile(/regexp/)

# good
/regexp/
Regexp.new('regexp')
Regexp.compile('regexp')

Style/RedundantRegexpEscape

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.85

-

检查正则表达式字面量中冗余的转义符。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.10

0.14

检查冗余的 return 表达式。

示例

# 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(默认)

# bad
def test
  return x, y
end

AllowMultipleReturnValues: true

# good
def test
  return x, y
end

可配置属性

名称 默认值 可配置值

AllowMultipleReturnValues

false

布尔值

Style/RedundantSelf

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.10

0.13

检查冗余的 self 使用。

仅在以下情况下需要使用 self

  • 在存在与参数或局部变量冲突的方法名称的情况下,向同一对象发送零参数的消息。

  • 调用属性写入器以防止局部变量赋值。

注意,使用显式 self,您只能发送具有公共或受保护范围的消息,您无法以这种方式发送私有消息。

注意,我们允许在运算符中使用 self,因为否则会很尴尬。还允许在块中使用 self.it 而不带参数,例如 0.times { self.it },遵循 Lint/ItWithoutArgumentsInBlock 规则。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.90

-

检查为就地修改方法进行冗余赋值的地方。

安全

此 cop 不安全,因为它可能会对具有预期名称之一但未就地修改其接收者的用户定义方法产生误报。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.19

-

检查条件分支进行冗余自赋值的地方。

它只检测局部变量,因为它可能会用 `nil` 替换跨方法具有状态的实例变量、类变量和全局变量的状态。

示例

# bad
foo = condition ? bar : foo

# good
foo = bar if condition

# bad
foo = condition ? foo : bar

# good
foo = bar unless condition

Style/RedundantSort

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.76

1.22

识别排序然后只取第一个或最后一个元素的情况。可以使用 `Enumerable#min` 而不是排序并取第一个元素,以及使用 `Enumerable#max` 而不是排序并取最后一个元素,来实现相同的行为,而无需进行相对昂贵的排序。类似地,`Enumerable#min_by` 和 `Enumerable#max_by` 可以替换 `Enumerable#sort_by` 调用,之后只使用第一个或最后一个元素。

安全

此 cop 不安全,因为 `sort…​last` 和 `max` 在所有情况下可能不会返回相同的元素。

在可枚举对象中,如果存在多个元素,其中 `a <⇒ b == 0`,或者 `sort_by` 块执行的转换具有相同的结果,则 `sort.last` 和 `max`(或 `sort_by.last` 和 `max_by`)将返回不同的元素。`sort.last` 将返回最后一个元素,但 `max` 将返回第一个元素。

例如

  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'

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.36

-

识别 `sort_by { …​ }` 可以用 `sort` 替换的地方。

示例

# bad
array.sort_by { |x| x }
array.sort_by do |var|
  var
end

# good
array.sort

Style/RedundantStringEscape

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.37

-

检查字符串文字中是否存在冗余转义。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.30

强制在正则表达式周围使用 `//` 或 `%r`。

以下使用正则表达式的 `%r` 情况,如果方法参数以空格或 `=` 开头,则允许防止语法错误。
do_something %r{ regexp} # `do_something / regexp/` is an invalid syntax.
do_something %r{=regexp} # `do_something /=regexp/` is an invalid syntax.

示例

EnforcedStyle: slashes(默认)

# bad
snake_case = %r{^[\dA-Z_]+$}

# bad
regex = %r{
  foo
  (bar)
  (baz)
}x

# good
snake_case = /^[\dA-Z_]+$/

# good
regex = /
  foo
  (bar)
  (baz)
/x

强制风格: 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

强制风格: 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 (默认)

# 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\//

可配置属性

名称 默认值 可配置值

EnforcedStyle

slashes

slashes, percent_r, mixed

AllowInnerSlashes

false

布尔值

Style/RequireOrder

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

1.40

-

按字母顺序排序requirerequire_relative

安全

此 cop 的自动更正不安全,因为它显然会改变执行顺序。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.34

检查rescue的修饰符形式的使用,原因如下

  • 修饰符形式rescue的语法可能具有误导性,因为它可能让我们相信rescue处理了给定的异常,但实际上它实际上会救援所有异常以返回给定的救援块。在这种情况下,由 handle_error 或 SomeException 返回的值。

  • 修饰符形式rescue将救援所有异常。它将静默地跳过所有异常或错误并处理错误。例如:如果引发了NoMethodError,修饰符形式的救援将处理异常。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.52

-

检查救援StandardError。支持两种风格implicitexplicit。如果指定了除StandardError以外的任何错误,此 cop 不会注册违规。

示例

强制风格: explicit (默认)

# `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

强制风格: 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

explicit

implicit, explicit

Style/ReturnNil

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.50

-

强制return nilreturn之间的一致性。

此 cop 默认情况下处于禁用状态。因为returnreturn nil之间似乎存在感知上的语义差异。前者可以被视为只是停止评估,而后者可能在返回值特别重要时使用。

支持的风格是returnreturn_nil

示例

强制风格: return (默认)

# bad
def foo(arg)
  return nil if arg
end

# good
def foo(arg)
  return if arg
end

强制风格: return_nil

# bad
def foo(arg)
  return if arg
end

# good
def foo(arg)
  return nil if arg
end

可配置属性

名称 默认值 可配置值

EnforcedStyle

返回

return, return_nil

Style/ReturnNilInPredicateMethodDefinition

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.53

-

检查谓词方法定义中是否使用returnreturn nil

安全性

自动更正被标记为不安全,因为返回值从nil更改为false可能会导致不兼容问题。

示例

# 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

AllowedMethods: ['foo?']

# good
def foo?
  return if condition

  do_something?
end

AllowedPatterns: [/foo/]

# good
def foo?
  return if condition

  do_something?
end

可配置属性

名称 默认值 可配置值

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

Style/SafeNavigation

所需 Ruby 版本:2.3
默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.43

1.27

将使用非nil检查保护的方法调用的用法转换为安全导航(&.)。如果存在方法链,则需要检查链中所有方法的安全性,并且所有方法都需要更改为使用安全导航。

ConvertCodeThatCanStartToReturnNil的默认值为false。当配置为true时,它将检查格式为!foo.nil? && foo.bar的代码。按照编写方式,此代码的返回值仅限于false以及方法的返回值。如果将其转换为安全导航,foo&.bar可以开始返回nil以及方法的返回值。

MaxChainLength的默认值为2。我们已将cop限制为不为超过此选项设置的方法链注册违规。

安全性

自动更正不安全,因为如果值为false,则生成的代码将具有不同的行为或引发错误。

x = false
x && x.foo  # return false
x&.foo      # raises NoMethodError

示例

# 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

可配置属性

名称 默认值 可配置值

ConvertCodeThatCanStartToReturnNil

false

布尔值

AllowedMethods

present?, blank?, presence, try, try!

数组

MaxChainLength

2

整数

Style/Sample

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.30

-

识别shuffle.firstshuffle.lastshuffle[]的用法,并将它们更改为使用sample

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.22

-

查找根据Regexp匹配计算可枚举子集(数组、范围、集合等;见下文说明)的位置,并建议使用grepgrep_v代替。

哈希在使用grep时不会像预期那样工作,这意味着hash.grep不等于hash.select。尽管 RuboCop 受限于静态分析,但此 cop 尝试在接收者为哈希(哈希文字、Hash.newHash#[]to_h/to_hash)时避免注册违规。
在 Ruby 3.0 中,当不使用块时,grepgrep_v进行了优化,但在之前的版本中可能速度较慢。请参阅https://bugs.ruby-lang.org/issues/17030

安全性

自动更正被标记为不安全,因为grep不会创建MatchData,但之前可能在match?=~调用后依赖它。

此外,cop 无法通过静态分析保证selectreject的接收者实际上是数组,因此更正可能并不完全等效。

示例

# bad (select 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.19

0.29

强制使用自赋值的简写形式。

示例

# bad
x = x + 1

# good
x += 1

Style/Semicolon

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.19

检查同一行上放置的多个表达式。它还检查以分号结尾的行。

此 cop 有AllowAsExpressionSeparator配置选项。它允许;在同一行上分隔多个表达式。

示例

# bad
foo = 1; bar = 2;
baz = 3;

# good
foo = 1
bar = 2
baz = 3

AllowAsExpressionSeparator: false(默认)

# bad
foo = 1; bar = 2

AllowAsExpressionSeparator: true

# good
foo = 1; bar = 2

可配置属性

名称 默认值 可配置值

AllowAsExpressionSeparator

false

布尔值

Style/Send

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

0.33

-

检查 send 方法的使用。

示例

# bad
Foo.send(bar)
quuz.send(fred)

# good
Foo.__send__(bar)
quuz.public_send(fred)

Style/SendWithLiteralMethodName

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.64

-

检测使用带有字面方法名参数的 public_send 方法。由于 send 方法可以用来调用私有方法,默认情况下,只检测 public_send 方法。

安全性

此 cop 不安全,因为它可能会根据接收者错误地进行检测。此外,当 AllowSend 设置为 true 时,它无法确定检测到的 send 方法是否正在调用私有方法。

示例

# bad
obj.public_send(:method_name)
obj.public_send('method_name')

# good
obj.method_name

AllowSend: true(默认)

# 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

可配置属性

名称 默认值 可配置值

AllowSend

true

布尔值

Style/SignalException

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.11

0.37

检查 failraise 的使用。

示例

EnforcedStyle: only_raise(默认)

# 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

可配置属性

名称 默认值 可配置值

EnforcedStyle

only_raise

only_raiseonly_failsemantic

Style/SingleArgumentDig

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.89

-

有时使用 dig 方法最终只使用一个参数。在这种情况下,应该用 [] 替换 dig。

由于将 hash&.dig(:key) 替换为 hash[:key] 可能导致错误,因此将忽略使用安全导航调用 dig 方法。

安全性

此 cop 不安全,因为它无法保证接收者是 Enumerable 或者没有 dig 的非标准实现。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.16

1.6

检查接受块的单行方法的块参数是否与配置中指定的名称匹配。

例如,可以将 reduceinject)配置为使用 |a, e| 作为参数。

配置选项:应将方法设置为使用此 cop。哈希数组,其中每个键是方法名称,值是参数名称数组。

示例

方法:[{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

可配置属性

名称 默认值 可配置值

方法

{"reduce"⇒["acc", "elem"]}, {"inject"⇒["acc", "elem"]}

数组

Style/SingleLineDoEndBlock

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.57

-

检查单行 do…​end 块。

在实践中,当 Style/BlockDelimiters 中的 EnforcedStyle: semantic 时,单行 do…​end 会自动更正。自动更正会保留 do …​ end 语法以保留语义,不会将其更改为 {…​} 块。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

1.8

检查包含主体的一行方法定义。它将接受没有主体的单行方法。

Ruby 3.0 中添加的无限方法也为此 cop 接受。

如果 Style/EndlessMethod 启用了 EnforcedStyle: allow_single_lineallow_always,如果主体中只有一条语句,则单行方法将自动更正为无限方法。

示例

# 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(默认)

# good
def no_op; end

AllowIfMethodIsEmpty: false

# bad
def no_op; end

可配置属性

名称 默认值 可配置值

AllowIfMethodIsEmpty

true

布尔值

Style/SlicingWithRange

所需的 Ruby 版本:2.6
默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.83

-

检查数组是否没有使用冗余的 ary[0..-1] 进行切片,将其替换为 ary,并确保数组在 Ruby 2.6+ 上使用无限范围而不是 ary[start..-1] 进行切片,在 Ruby 2.7+ 上使用无头范围而不是 ary[nil..end] 进行切片。

安全

此 cop 不安全,因为 x..-1x.. 仅保证对于 Array#[]String#[] 等效,而 cop 无法确定接收者的类。

例如

sum = proc { |ary| ary.sum }
sum[-3..-1] # => -6
sum[-3..] # Hangs forever

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.89

1.5

如果条件分支仅包含一个条件节点,则可以将其条件与外部分支的条件合并。这有助于防止嵌套级别过深。

示例

# 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(默认)

# 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

可配置属性

名称 默认值 可配置值

AllowModifier

false

布尔值

Style/SpecialGlobalVars

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.13

0.36

查找 Perl 风格的全局变量的使用。如果通过 RequireEnglish 配置启用,则更正为 'English' 库中的全局变量将向文件顶部添加 require 语句。

安全性

自动更正被标记为不安全,因为如果 RequireEnglish 不为真,则用英文变量替换 perl 风格的变量会导致程序崩溃。

示例

EnforcedStyle: use_english_names(默认)

# 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 $*

可配置属性

名称 默认值 可配置值

RequireEnglish

true

布尔值

EnforcedStyle

use_english_names

use_perl_names, use_english_names, use_builtin_english_names

Style/StabbyLambdaParentheses

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.35

-

检查 stabby lambda 参数周围的括号。有两种不同的风格。默认为 require_parentheses

示例

EnforcedStyle: require_parentheses(默认)

# 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}

可配置属性

名称 默认值 可配置值

EnforcedStyle

require_parentheses

require_parentheses, require_no_parentheses

Style/StaticClass

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

1.3

-

检查只有类方法的类可以被模块替换的地方。类应该只在需要创建实例时使用。

安全性

此 cop 不安全,因为该类可能是其他子类的父类,可能被实例方法修补或在某个地方从其创建了虚拟实例。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.51

-

识别可以使用 warn 替换 $stderr.puts 的地方。后者具有通过 -W0 解释器标志或将 $VERBOSE 设置为 nil 来轻松禁用的优点。

示例

# bad
$stderr.puts('hello')

# good
warn('hello')

Style/StringChars

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.12

-

检查使用空字符串或正则表达式字面量参数的 String#split 的情况。

安全性

此 cop 不安全,因为无法保证接收器实际上是字符串。如果另一个类具有具有不同行为的 split 方法,它将被注册为误报。

示例

# bad
string.split(//)
string.split('')

# good
string.chars

Style/StringConcatenation

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.89

1.18

检查可以使用字符串插值替换字符串连接的地方。

cop 可以自动更正简单的情况,但会跳过自动更正更复杂的情况,因为生成的代码将更难阅读。在这些情况下,将语句提取到局部变量或方法中可能会有用,然后你可以在字符串中插值它们。

当两个字符串之间的连接跨越多行时,此 cop 不会注册违规;相反,如果启用,Style/LineEndConcatenation 将拾取违规。

支持两种模式:1. aggressive 风格检查并更正所有 + 的出现,其中 + 的左侧或右侧是字符串字面量。2. 另一方面,conservative 风格仅在左侧(+ 方法调用的接收器)是字符串字面量时检查和更正。当接收器是返回字符串的某些表达式(如 Pathname)而不是字符串字面量时,这很有用。

安全性

此 cop 在 aggressive 模式下不安全,因为它无法保证接收器实际上是字符串,这会导致误报。

示例

模式:aggressive(默认)

# 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'

模式:conservative

# bad
'Hello' + user.name

# good
"Hello #{user.name}"
user.name + '!!'
Pathname.new('/') + 'test'

可配置属性

名称 默认值 可配置值

模式

aggressive

String

Style/StringHashKeys

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

0.52

0.75

检查哈希中是否使用字符串作为键。建议使用符号代替。

安全性

此 cop 不安全,因为虽然符号是哈希键的首选,但在某些情况下需要使用字符串键。

示例

# bad
{ 'one' => 1, 'two' => 2, 'three' => 3 }

# good
{ one: 1, two: 2, three: 3 }

Style/StringLiterals

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.36

检查引号的使用是否符合配置的偏好。

示例

EnforcedStyle: single_quotes(默认)

# 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"

可配置属性

名称 默认值 可配置值

EnforcedStyle

single_quotes

single_quotesdouble_quotes

ConsistentQuotesInMultiline

false

布尔值

Style/StringLiteralsInInterpolation

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.27

-

检查字符串、符号和正则表达式插值中的引号是否符合配置的偏好。

示例

EnforcedStyle: single_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'}/

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"}/

可配置属性

名称 默认值 可配置值

EnforcedStyle

single_quotes

single_quotesdouble_quotes

Style/StringMethods

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

Always

0.34

0.34

强制使用 String 类中一致的方法名。

示例

# bad
'name'.intern
'var'.unfavored_method

# good
'name'.to_sym
'var'.preferred_method

可配置属性

名称 默认值 可配置值

PreferredMethods

{"intern"⇒"to_sym"}

Style/Strip

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.36

-

识别可以将 lstrip.rstrip 替换为 strip 的位置。

示例

# bad
'abc'.lstrip.rstrip
'abc'.rstrip.lstrip

# good
'abc'.strip

Style/StructInheritance

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.29

1.20

检查是否从 Struct.new 继承。

安全性

自动更正不安全,因为它会更改常量的继承树(例如 Module#ancestors 的返回值)。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.64

-

检查使用与方法定义相同的参数调用 super 时是否冗余地转发参数。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.58

-

强制在包含参数的 super 中使用括号。

super 是一个关键字,它与用于方法调用的关键字不同。

示例

# bad
super name, age

# good
super(name, age)

Style/SwapValues

默认启用 安全 支持自动更正 添加版本 更改版本

待定

始终(不安全)

1.1

-

强制使用简写方式交换两个变量。

安全性

自动更正不安全,因为用于交换变量的临时变量将被删除,但可能在其他地方被引用。

示例

# bad
tmp = x
x = y
y = tmp

# good
x, y = y, x

Style/SymbolArray

所需 Ruby 版本:2.0
默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.49

检查由符号组成的数组字面量是否使用 %i() 语法。

或者,它检查使用 %i() 语法的符号数组,这些数组在不希望使用该语法的项目中,可能是因为它们支持低于 2.0 的 Ruby 版本。

配置选项:MinSize 如果设置,则元素数量少于此值的数组不会触发 cop。例如,MinSize3 将不会对元素数量为 2 或更少的数组强制执行样式。

示例

EnforcedStyle: percent(默认)

# 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]

可配置属性

名称 默认值 可配置值

EnforcedStyle

percent

percentbrackets

MinSize

2

整数

Style/SymbolLiteral

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.30

-

检查符号字面量语法。

示例

# bad
:"symbol"

# good
:symbol

Style/SymbolProc

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.26

1.64

尽可能使用符号作为 proc。

如果您更喜欢允许带参数的方法使用块的样式,请将 AllowMethodsWithArguments 设置为 truedefine_method? 方法默认允许。这些可以通过 AllowedMethods 选项进行自定义。

安全性

此 cop 不安全,因为 Symbol#to_proc 生成的 Proc 作为 lambda 行为,而从块生成的 Proc 则不。例如,如果参数数量错误,lambda 将引发 ArgumentError,但非 lambda Proc 不会。

例如

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)

它也不安全,因为 Symbol#to_proc 不适用于 protected 方法,否则这些方法是可以访问的。

例如

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...>

示例

# bad
something.map { |s| s.upcase }
something.map { _1.upcase }

# good
something.map(&:upcase)

AllowMethodsWithArguments: false(默认)

# 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(默认)

# 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] (默认)

# good
define_method(:foo) { |foo| foo.bar }

AllowedPatterns: [] (默认)

# bad
something.map { |s| s.upcase }

AllowedPatterns: ['map'] (默认)

# good
something.map { |s| s.upcase }

AllCops:ActiveSupportExtensionsEnabled: false (默认)

# 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 }

可配置属性

名称 默认值 可配置值

AllowMethodsWithArguments

false

布尔值

AllowedMethods

define_method

数组

AllowedPatterns

[]

数组

AllowComments

false

布尔值

Style/TernaryParentheses

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.42

0.46

检查三元条件周围是否存在括号。可以使用 EnforcedStyle 配置强制包含或省略括号。只有在删除括号不会导致不同行为的情况下,才会强制省略括号。

AllowSafeAssignment 选项用于安全赋值。安全赋值是指在赋值周围加上括号,表示“我知道我正在使用赋值作为条件,这不是错误”。

示例

EnforcedStyle: require_no_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

# 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 (默认)

# good
foo = (bar = baz) ? a : b

AllowSafeAssignment: false

# bad
foo = (bar = baz) ? a : b

可配置属性

名称 默认值 可配置值

EnforcedStyle

require_no_parentheses

require_parentheses, require_no_parentheses, require_parentheses_when_complex

AllowSafeAssignment

true

布尔值

Style/TopLevelMethodDefinition

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

1.15

-

Ruby 应用程序的新手可能会编写顶层方法,而理想情况下,它们应该在适当的类或模块中组织。此 cop 会查找顶层方法的定义并发出警告。

但是,对于 ruby 脚本,使用顶层方法是完全可以的。因此,此 cop 默认情况下处于禁用状态。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.53

-

检查类定义后的尾随代码。

示例

# bad
class Foo; def foo; end
end

# good
class Foo
  def foo; end
end

Style/TrailingBodyOnMethodDefinition

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.52

-

检查方法定义后的尾部代码。

它始终接受基本上在同一行上的无限方法定义。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.53

-

检查模块定义后的尾部代码。

示例

# bad
module Foo extend self
end

# good
module Foo
  extend self
end

Style/TrailingCommaInArguments

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.36

-

检查参数列表中的尾部逗号。支持的样式为

  • consistent_comma:对于所有带参数的带括号的方法调用,要求在最后一个参数后添加逗号。

  • comma:要求在最后一个参数后添加逗号,但仅适用于每个参数都在其自身行上的带括号的方法调用。

  • no_comma:要求在最后一个参数后没有逗号。

示例

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(默认)

# bad
method(1, 2,)

# good
method(1, 2)

# good
method(
  1,
  2
)

可配置属性

名称 默认值 可配置值

EnforcedStyleForMultiline

no_comma

commaconsistent_commano_comma

Style/TrailingCommaInArrayLiteral

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.53

-

检查数组文字中的尾部逗号。配置选项为

  • consistent_comma:要求在所有非空、多行数组文字的最后一个项目后添加逗号。

  • comma:要求在数组的最后一个项目后添加逗号,但仅当每个项目都在其自身行上时。

  • no_comma:不要求在数组的最后一个项目后添加逗号

示例

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(默认)

# bad
a = [1, 2,]

# good
a = [
  1,
  2
]

可配置属性

名称 默认值 可配置值

EnforcedStyleForMultiline

no_comma

commaconsistent_commano_comma

Style/TrailingCommaInBlockArgs

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

0.81

-

检查块参数中是否需要尾部逗号。只有一个参数且带尾部逗号的块需要该逗号。具有多个参数的块永远不需要尾部逗号。

安全

此 cop 不安全,因为尾部逗号可能表示存在未使用的更多参数。

例如

# 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]]

可以通过用占位符参数(例如 |key, _value|)替换尾部逗号来解决此问题。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.53

-

检查哈希文字中的尾部逗号。配置选项为

  • consistent_comma:要求所有非空、多行哈希文字的最后一个项目后都有逗号。

  • comma:要求哈希的最后一个项目后有逗号,但仅当每个项目都在其自己的行上时。

  • no_comma:不要求哈希的最后一个项目后有逗号

示例

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 (默认)

# bad
a = { foo: 1, bar: 2, }

# good
a = {
  foo: 1,
  bar: 2
}

可配置属性

名称 默认值 可配置值

EnforcedStyleForMultiline

no_comma

commaconsistent_commano_comma

Style/TrailingMethodEndStatement

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.52

-

检查方法定义后的尾部代码。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.31

0.35

检查变量赋值中是否有额外的下划线。

示例

# 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 (默认)

# good
a, b, _something = foo()

AllowNamedUnderscoreVariables: false

# bad
a, b, _something = foo()

可配置属性

名称 默认值 可配置值

AllowNamedUnderscoreVariables

true

布尔值

Style/TrivialAccessors

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

1.15

查找可以使用 attr_* 函数族自动创建的琐碎读写器方法。默认情况下,允许 to_aryto_ato_cto_enumto_hto_hashto_ito_intto_ioto_opento_pathto_procto_rto_regexpto_strto_sto_sym 方法。这些方法可以使用 AllowedMethods 选项进行自定义。

示例

# 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(默认)

# good
def name
  @other_name
end

ExactNameMatch: false

# bad
def name
  @other_name
end

AllowPredicates: true(默认)

# good
def foo?
  @foo
end

AllowPredicates: false

# bad
def foo?
  @foo
end

# good
attr_reader :foo

AllowDSLWriters: true(默认)

# 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(默认)

# 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

可配置属性

名称 默认值 可配置值

ExactNameMatch

true

布尔值

AllowPredicates

true

布尔值

AllowDSLWriters

true

布尔值

IgnoreClassMethods

false

布尔值

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

数组

Style/UnlessElse

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

-

查找带有else子句的unless表达式。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

1.11

-

检查unless条件中是否使用了逻辑运算符。它不鼓励这种代码,因为条件变得更难阅读和理解。

此 cop 支持两种风格

  • forbid_mixed_logical_operators(默认)

  • forbid_logical_operators

forbid_mixed_logical_operators风格禁止使用多种类型的逻辑运算符。这使得unless条件更容易阅读,因为所有条件都需要满足或任何条件都需要满足才能使表达式为真或假。

forbid_logical_operators风格禁止使用任何逻辑运算符。这使得阅读unless条件变得更加容易,因为表达式中只有一个条件。

示例

EnforcedStyle: forbid_mixed_logical_operators(默认)

# 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?

可配置属性

名称 默认值 可配置值

EnforcedStyle

forbid_mixed_logical_operators

forbid_mixed_logical_operators, forbid_logical_operators

Style/UnpackFirst

所需 Ruby 版本:2.4
默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.54

-

检查访问String#unpack的第一个元素,该元素可以用更短的方法unpack1替换。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.20

检查变量插值(如“#@ivar”)。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

-

检查case表达式中使用when;

示例

# bad
case foo
when 1; 'baz'
when 2; 'bar'
end

# good
case foo
when 1 then 'baz'
when 2 then 'bar'
end

Style/WhileUntilDo

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

-

检查在多行while/until语句中使用do

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

0.30

检查可以作为修饰符 while/until 写在一行上的 while 和 until 语句。最大行长在Layout/LineLength cop 中配置。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

Always

0.9

1.19

检查由类似单词的字符串组成的数组字面量,这些字面量没有使用 %w() 语法。

或者,它可以检查在不希望包含该语法的项目中使用 %w() 语法。

使用percent样式时,包含空格的 %w() 数组将被注册为违规。

配置选项:MinSize 如果设置,则元素数量少于此值的数组不会触发 cop。例如,MinSize3 将不会对元素数量为 2 或更少的数组强制执行样式。

示例

EnforcedStyle: percent(默认)

# 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]
]

可配置属性

名称 默认值 可配置值

EnforcedStyle

percent

percentbrackets

MinSize

2

整数

WordRegex

(?-mix:\A(?:\p{Word}|\p{Word}-\p{Word}|\n|\t)+\z)

Style/YAMLFileRead

默认启用 安全 支持自动更正 添加版本 更改版本

待定

Always

1.53

-

检查使用YAML.loadYAML.safe_loadYAML.parse以及File.read参数。

YAML.safe_load_file是在 Ruby 3.0 中引入的。

示例

# 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

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.49

0.75

强制或禁止 Yoda 条件,即表达式顺序颠倒的比较运算。例如5 == x

安全

此代码不安全,因为比较运算符在不同的类中可能定义不同,并且在反转时不能保证得到相同的结果。

例如

class MyKlass
  def ==(other)
    true
  end
end

obj = MyKlass.new
obj == 'string'   #=> true
'string' == obj   #=> false

示例

EnforcedStyle: forbid_for_all_comparison_operators(默认)

# 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

可配置属性

名称 默认值 可配置值

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

默认启用 安全 支持自动更正 添加版本 更改版本

已禁用

始终(不安全)

1.42

1.43

禁止 Yoda 表达式,即二元运算(使用 *+&|^ 运算符),其中表达式的顺序颠倒,例如 1 + x。此代码与 Style/YodaCondition 代码互补,它们具有相似的目的。

此代码默认情况下处于禁用状态,以尊重用户的意图,例如

config.server_port = 9000 + ENV["TEST_ENV_NUMBER"].to_i

安全性

此代码不安全,因为二元运算符在不同的类中可能定义不同,并且在反转时不能保证得到相同的结果。

示例

SupportedOperators: ['*', '+', '&', '|', '^'](默认)

# 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

可配置属性

名称 默认值 可配置值

Style/ZeroLengthPredicate

默认启用 安全 支持自动更正 添加版本 更改版本

启用

始终(不安全)

0.37

0.39

检查可以被谓词方法替换的数字比较,例如 receiver.length == 0receiver.length > 0receiver.length != 0receiver.length < 1receiver.size == 0,它们可以被 receiver.empty?!receiver.empty? 替换。

FileTempfileStringIO 没有 empty?,因此允许 size == 0size.zero?

安全性

此代码不安全,因为它无法保证接收者具有根据 length 定义的 empty? 方法。如果存在重新定义 lengthempty? 的非标准类,则代码可能会注册误报。

示例

# 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?