样式
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
Style/AccessorGrouping
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.87 |
- |
检查 class
和 module
代码块中访问器的分组。默认情况下,它强制访问器放置在分组声明中,但可以配置为强制将它们分开在多个声明中。
如果在访问器方法之前有方法调用,则始终允许,因为它可能是像 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
Style/Alias
Style/AndOr
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
来禁用此功能。
此外,此代码检查器具有 RedundantRestArgumentNames
、RedundantKeywordRestArgumentNames
和 RedundantBlockArgumentNames
选项。此配置是一个冗余名称列表,这些名称足以匿名化无意义的命名。
通常使用的无意义名称可以默认匿名化:例如,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
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"]
Style/ArrayFirstLast
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
Style/ArrayJoin
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.20 |
0.31 |
检查使用 "*" 作为 join 的替代品。
由于 Ruby 的动态类型,并非所有情况都能可靠地检查,因此我们只考虑第一个参数是数组字面量或第二个参数是字符串字面量的情况。
Style/AsciiComments
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
否 |
0.9 |
1.21 |
检查注释中是否存在非 ASCII(非英语)字符。您可以在 AllowedChars
属性中设置允许的非 ASCII 字符数组(默认情况下为版权声明 "©")。
Style/Attr
Style/BarePercentLiterals
Style/BlockDelimiters
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.30 |
0.35 |
检查单行或多行代码块周围使用大括号或 do/end。
无法从其用法单独分类的既可以是过程式也可以是函数式的函数将被忽略。lambda
、proc
和 it
是它们的默认值。可以将其他方法添加到 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
可配置属性
名称 | 默认值 | 可配置值 |
---|---|---|
EnforcedStyle |
|
|
ProceduralMethods |
|
数组 |
FunctionalMethods |
|
数组 |
AllowedMethods |
|
数组 |
AllowedPatterns |
|
数组 |
AllowBracesOnProceduralOneLiners |
|
布尔值 |
BracesRequiredMethods |
|
数组 |
Style/CaseEquality
Style/CaseLikeIf
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.88 |
1.48 |
识别 if-elsif
结构可以被 case-when
替换的地方。
示例
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
Style/CharacterLiteral
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
- |
检查对字符字面量 ?x 的使用。从 Ruby 1.9 开始,字符字面量本质上是一字符字符串,因此这种语法在此时大多是多余的。
? 字符字面量可用于表示元字符和控制字符。这是 ? 字面量的一个很好的用例,因此它不会将其视为违规。
Style/ClassAndModuleChildren
Style/ClassCheck
Style/ClassEqualityComparison
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.93 |
1.57 |
强制使用Object#instance_of?
而不是类比较来判断相等性。默认情况下允许==
、equal?
和eql?
自定义方法定义。这些可以通过AllowedMethods
选项进行自定义。
示例
# bad
var.class == Date
var.class.equal?(Date)
var.class.eql?(Date)
var.class.name == 'Date'
# good
var.instance_of?(Date)
Style/ClassMethods
Style/ClassMethodsDefinitions
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
Always |
0.89 |
- |
强制使用def self.method_name
或class << 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
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!
Style/CollectionMethods
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
否 |
始终(不安全) |
0.9 |
1.7 |
强制使用 Enumerable 模块中一致的方法名。
您可以自定义从不希望使用的方法到希望使用的方法的映射。
例如,使用 detect
代替 find
Style/CollectionMethods: PreferredMethods: find: detect
示例
# 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?
Style/ColonMethodCall
Style/CombinableLoops
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.90 |
- |
检查多个连续循环遍历相同数据的地方是否可以合并为单个循环。合并它们很可能使代码更高效和更简洁。
示例
# 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
)
Style/CommentAnnotation
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.10 |
1.20 |
检查注释标注关键字是否符合指南。
可以通过覆盖 cop 的 Keywords
配置来指定标注关键字。关键字可以是单个单词或短语。
对于多行注释块(其中每一行都只是一个注释),只有第一行才能注册违规,即使标注关键字在另一行开始。这样做是为了防止在段落中错误地注册关键字(例如 review )作为标注。
|
Style/CommentedKeyword
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.51 |
1.19 |
检查与某些关键字位于同一行的注释。这些关键字是:class
, module
, def
, begin
, end
。
请注意,某些注释(:nodoc:
, :yields:
, rubocop:disable
和 rubocop:todo
)是允许的。
自动更正会从 end
关键字中删除注释,并将 class
, module
, def
和 begin
的注释保留在关键字上方。
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)
Style/ConcatArrayLiterals
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.41 |
- |
强制使用 Array#push(item)
而不是 Array#concat([item])
来避免冗余的数组字面量。
Style/ConditionalAssignment
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.36 |
0.47 |
检查 if
和 case
语句,其中每个分支都用于同一个变量的赋值和比较,而使用条件的返回值可以代替。
示例
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
Style/ConstantVisibility
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
否 |
0.66 |
1.10 |
检查类和模块中定义的常量是否具有显式的可见性声明。默认情况下,Ruby 使所有类和模块常量都公开,这会使类或模块的公共 API 混乱。显式声明可见性可以使意图更加清晰,并防止外部参与者触碰私有状态。
Style/Copyright
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
Always |
0.30 |
- |
检查每个源文件中是否提供了版权声明。
可以在 config/default.yml 中找到可接受版权声明的默认正则表达式。默认值可以按如下方式更改
Style/Copyright:
Notice: '^Copyright (\(c\) )?2\d{3} Acme Inc'
此正则表达式字符串被视为未锚定的正则表达式。对于 RuboCop 扫描的每个文件,必须找到与该正则表达式匹配的注释,否则会报告违规。
Style/DataInheritance
Style/DateTime
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
始终(不安全) |
0.51 |
0.92 |
检查是否一致地使用 DateTime
类而不是 Time
类。此 cop 默认情况下处于禁用状态,因为这些类虽然高度重叠,但具有特殊性,在处理多个时区和/或 DST 时,在某些情况下无法替换它们。
示例
# 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)
Style/DefWithParentheses
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
0.12 |
检查不带参数的方法定义中是否有括号。 同时检查实例方法和类/单例方法。
Style/DisableCopsWithinSourceCodeDirective
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
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
Style/DoubleCopDisableDirective
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.73 |
- |
检测一行上的双重禁用注释。这主要是为了捕获需要重新生成的自动生成的注释。
Style/DoubleNegation
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.19 |
1.2 |
检查使用双重否定(!!
)将某些内容转换为布尔值的情况。
当使用 EnforcedStyle: allowed_in_returns
时,允许在使用布尔值作为返回值的上下文中使用双重否定。当使用 EnforcedStyle: forbidden
时,应始终禁止双重否定。
当 something 是一个布尔值时,!!something 和 !something.nil? 并不相同。由于您不太可能编写可以接受任何类型值的代码,因此在实践中这很少是一个问题。
|
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
Style/EmptyMethod
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
仅命令行 |
0.46 |
1.61 |
检查空方法定义的格式。默认情况下,它强制空方法定义在一行上(紧凑样式),但可以配置为强制end
在它自己的行上(扩展样式)。
如果方法定义包含注释,则不认为它是空的。 |
如果生成的代码比Layout/LineLength 的Max 配置更长,则不会对compact 样式应用自动更正,但仍会注册违规。
|
Style/EndlessMethod
必需的 Ruby 版本:3.0 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
Always |
1.8 |
- |
检查无穷方法。
它可以强制执行对单行方法体使用无穷方法定义,或者禁止无穷方法。
此 cop 不考虑其他方法定义类型。
支持的样式是
-
allow_single_line(默认) - 仅允许单行无穷方法定义。
-
allow_always - 允许所有无穷方法定义。
-
disallow - 禁止所有无穷方法定义。
不正确的无穷方法定义将始终被更正为多行定义。 |
Style/EnvHome
Style/EvalWithLocation
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.52 |
- |
确保 eval 方法(eval
、instance_eval
、class_eval
和 module_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?
的地方。
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
Style/FetchEnvVar
Style/FileEmpty
所需 Ruby 版本:2.4 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.48 |
- |
在检查文件是否为空时,建议使用 File.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
Style/For
Style/FormatString
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.19 |
0.49 |
强制使用单个字符串格式化实用程序。有效选项包括 Kernel#format
、Kernel#sprintf
和 String#%
。
无法以可靠的方式对所有情况下的 String#%
进行检测,因此只考虑两种情况 - 如果第一个参数是字符串文字,以及如果第二个参数是数组文字。
当使用参数是文字或已知的内置转换方法(如 to_d
、to_f
、to_h
、to_i
、to_r
、to_s
和 to_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]'
Style/FormatStringToken
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.49 |
1.0 |
使用一致的样式命名格式字符串标记。
unannotated 样式检查器仅适用于作为参数传递给以下方法的字符串:printf 、sprintf 、format 、% 。原因是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)
Style/FrozenStringLiteralComment
所需 Ruby 版本:2.3 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.36 |
0.79 |
帮助您从可变字符串字面量过渡到冻结字符串字面量。它将在文件的顶部添加 # frozen_string_literal: true
魔法注释以启用冻结字符串字面量。冻结字符串字面量在未来的 Ruby 中可能是默认的。该注释将添加到 shebang 和编码注释下方。冻结字符串字面量注释仅在 Ruby 2.3+ 中有效。
请注意,检查器将接受存在注释但设置为 false
而不是 true
的文件。
要在此注释后要求空行,请参阅 Layout/EmptyLineAfterMagicComment
检查器。
示例
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
Style/GlobalStdStream
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.89 |
- |
强制使用$stdout/$stderr/$stdin
而不是STDOUT/STDERR/STDIN
。STDOUT/STDERR/STDIN
是常量,虽然你实际上可以在 Ruby 中重新分配常量(可能用于重定向某些流),但如果你这样做,你会得到解释器的警告。
Style/GlobalVars
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.13 |
- |
查找全局变量的使用。它不会报告内置全局变量的违规。默认情况下允许内置全局变量。此外,用户可以通过AllowedVariables选项允许其他变量。
请注意,像 $1、$2 等等这样的反向引用不是全局变量。
Style/GuardClause
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.20 |
1.31 |
使用保护子句而不是将代码包装在条件表达式中
除非在条件表达式的正文中使用了return
、break
、next
、raise
或fail
,否则允许带有elsif
或else
分支的条件。
自动更正适用于大多数情况,除了包含逻辑运算符(如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
Style/HashAsLastArrayItem
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)
Style/HashEachMethods
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.80 |
1.16 |
检查 each_key
和 each_value
哈希方法的使用情况。
如果您有一个包含两个元素数组的数组,您可以将括号放在块参数周围以指示您不是在使用哈希,并抑制 RuboCop 违规。 |
Style/HashExcept
必需的 Ruby 版本:3.0 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.7 |
1.39 |
检查使用 Hash#reject
、Hash#select
和 Hash#filter
方法的情况,这些方法可以用 Hash#except
方法替换。
此 cop 应该只在 Ruby 版本 3.0 或更高版本上启用。(Hash#except
在 Ruby 3.0 中添加。)
为了安全检测,它仅限于在使用 ==
时常用的字符串和符号比较。并且不要检查 Hash#delete_if
和 Hash#keep_if
来更改接收器对象。
示例
# 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]
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
强制风格: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}
Style/HashTransformKeys
所需 Ruby 版本:2.5 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.80 |
0.90 |
查找使用 _.each_with_object({}) {…}
, \_.map {…}.to_h
和 Hash[\_.map {…}]
实际上只是转换哈希键的情况,并尝试使用更简单且更快的 transform_keys
调用来代替。它应该只在 Ruby 版本 2.5 或更高版本上启用。(transform_keys
在 Ruby 2.5 中添加。)
示例
# 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_h
和 Hash[\_.map {…}]
实际上只是转换哈希值的情况,并尝试使用更简单且更快的 transform_values
调用来代替。
示例
# 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
Style/IfUnlessModifier
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
0.30 |
检查可以作为修饰符 if
/unless
写在一行上的 if
和 unless
语句。该 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/IfWithBooleanLiteralBranches
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终(不安全) |
1.9 |
- |
检查具有布尔文字分支的冗余 if
。它仅检查返回布尔值(true
或 false
)的条件,以进行安全检测。要检查的条件是比较方法、谓词方法和双重否定(!!)。默认情况下允许 nonzero?
方法。这些可以通过 AllowedMethods
选项自定义。
此 cop 仅针对具有单个 elsif
或 else
分支的 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
Style/IfWithSemicolon
Style/InPatternThen
Style/InverseMethods
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.48 |
- |
检查在方法上调用 not(not
或 !
)的情况,在这种情况下可以使用该方法的逆方法。
可以通过 not(not
或 !
)反转的方法应在 InverseMethods
中定义。
通过反转传递给方法的块的返回值来反转的方法应在 InverseBlocks
中定义。
示例
# 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
Style/InvertibleUnlessCondition
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
否 |
始终(不安全) |
1.44 |
1.50 |
检查使用unless
的情况,这些情况可以用if
和反转的条件来替换。没有unless
的代码更容易阅读,但这只是主观的,所以这个cop默认情况下是禁用的。
可以反转的方法应该在InverseMethods
中定义。注意,逆方法的关系需要在两个方向上定义。例如,
InverseMethods:
:!=: :==
:even?: :odd?
:odd?: :even?
将建议同时反转even?
和odd?
,但只反转!=
(而不是==
)。
示例
# 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
Style/IpAddresses
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
否 |
0.58 |
0.91 |
检查硬编码的IP地址,这会导致代码变得脆弱。IP地址很可能需要在代码部署到不同的服务器或环境时进行更改,如果忘记更改,可能会导致部署失败。建议在ENV或其他配置中设置IP地址。
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强制执行其中一种样式。
Style/MagicCommentFormat
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
Always |
1.35 |
- |
确保在整个代码库中一致地编写魔术注释。查找分隔符(-
与 _
)和魔术注释指令和值的区分大小写之间的差异。
可以使用 DirectiveCapitalization
和 ValueCapitalization
配置键设置所需的大小写。
如果其中一个配置设置为 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
Style/MapCompactWithConditionalBlock
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
Always |
1.30 |
- |
优先使用 select
或 reject
而不是 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
与 <<
、push
或 append
的情况,这些情况可以用 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
)。
Style/MapToHash
所需的 Ruby 版本:2.6 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.24 |
- |
查找使用 map.to_h
或 collect.to_h
的情况,这些情况可以在 Ruby >= 2.6 中仅使用 to_h
来编写。
Style/HashTransformKeys 和 Style/HashTransformValues 也会更改此模式,如果仅转换哈希键或哈希值。
|
Style/MapToSet
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.42 |
- |
查找使用 map.to_set
或 collect.to_set
的情况,这些情况可以使用 to_set
来编写。
Style/MethodCallWithArgsParentheses
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
Always |
0.47 |
1.7 |
强制在包含参数的方法调用中使用(默认)或不使用括号。
在默认样式(require_parentheses)中,允许使用宏方法。可以将其他方法添加到 AllowedMethods
或 AllowedPatterns
列表中。这些选项仅在默认样式中有效。可以通过将 IgnoreMacros
设置为 false 或将特定宏添加到 IncludedMacros
列表中来包含宏。
选项的优先级如下
-
AllowedMethods
-
AllowedPatterns
-
IncludedMacros
如果一个方法同时出现在 IncludedMacros
和 AllowedMethods
中,则后者优先(即,该方法是允许的)。
在备用样式(omit_parentheses)中,还有三个额外的选项。
-
AllowParenthesesInChaining
默认情况下为false
。将其设置为true
允许在方法链中的最后一个调用中使用括号。 -
AllowParenthesesInMultilineCall
默认值为false
。将其设置为true
允许在多行方法调用中使用括号。 -
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
AllowParenthesesInMultilineCall:false(默认)
# bad
foo.enforce(
strict: true
)
# good
foo.enforce \
strict: true
AllowParenthesesInMultilineCall:true
# good
foo.enforce(
strict: true
)
# good
foo.enforce \
strict: true
可配置属性
名称 | 默认值 | 可配置值 |
---|---|---|
忽略宏 |
|
布尔值 |
AllowedMethods |
|
数组 |
AllowedPatterns |
|
数组 |
IncludedMacros |
|
数组 |
AllowParenthesesInMultilineCall |
|
布尔值 |
AllowParenthesesInChaining |
|
布尔值 |
AllowParenthesesInCamelCaseMethod |
|
布尔值 |
AllowParenthesesInStringInterpolation |
|
布尔值 |
EnforcedStyle |
|
|
Style/MethodCallWithoutArgsParentheses
Style/MethodCalledOnDoEndBlock
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
否 |
0.14 |
- |
检查在 do…end 块上调用的方法。此检查的目的是,在阅读代码时很容易错过附加到块的调用。
Style/MethodDefParentheses
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.16 |
1.7 |
检查方法定义中参数周围的括号。检查实例方法和类/单例方法。
无论样式如何,以下情况都需要括号:
-
无限方法
-
包含
forward-arg
(…
) 的参数列表 -
包含匿名剩余参数转发 (
*
) 的参数列表 -
包含匿名关键字剩余参数转发 (
**
) 的参数列表 -
包含匿名块转发 (
&
) 的参数列表
在此处删除括号将导致语法错误。
示例
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
Style/MinMaxComparison
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.42 |
- |
强制使用 max
或 min
代替比较运算符来判断大于或小于。
如果您想在 Ruby 2.7+ 中表示限制或阈值,可以使用此规则。但是,这种方法速度较慢。因此,自动更正将应用通用的 max 或 min 。
|
a.clamp(b..) # Same as `[a, b].max`
a.clamp(..b) # Same as `[a, b].min`
Style/MissingElse
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
Always |
0.30 |
0.38 |
检查没有 else
分支的 if
表达式。
模式匹配允许没有 else 分支,因为与 if 和 case 不同,如果模式不匹配,它会引发 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
Style/MissingRespondToMissing
Style/MixinGrouping
Style/ModuleFunction
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.11 |
0.65 |
检查模块中是否使用extend self
或module_function
。
支持的样式有:module_function
(默认)、extend_self
和forbidden
。
需要注意以下几点
-
forbidden
样式禁止使用这两种样式 -
在默认模式(
module_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
Style/MultilineBlockChain
Style/MultilineIfThen
Style/MultilineInPatternThen
Style/MultilineTernaryOperator
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
0.86 |
检查多行三元运算符表达式。
return if … else … end 是语法错误。如果在多行三元运算符表达式之前使用 return ,它将自动更正为单行三元运算符。对于 break 、next 和方法调用也是如此。
|
Style/MultilineWhenThen
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
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 允许对常量进行显式冻结。
|
示例
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]
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
Style/NegatedUnless
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.69 |
- |
检查使用带否定条件的 unless。仅考虑没有 else 的 unless。有三种不同的风格
-
both
-
prefix
-
postfix
Style/NegatedWhile
Style/NestedModifier
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.35 |
- |
检查 if、unless、while 和 until 的修饰符形式的嵌套使用。
Style/NestedParenthesizedCalls
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.36 |
0.77 |
检查带括号的方法调用参数列表中的未带括号的方法调用。be
、be_a
、be_an
、be_between
、be_falsey
、be_kind_of
、be_instance_of
、be_truthy
、be_within
、eq
、eql
、end_with
、include
、match
、raise_error
、respond_to
和 start_with
方法默认允许。这些方法可以使用 AllowedMethods
选项进行自定义。
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
Style/NilComparison
Style/NonNilCheck
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.20 |
0.22 |
检查非 nil 检查,这些检查通常是多余的。
默认情况下,IncludeSemanticChanges
设置为 false
,此 cop 不会报告 !x.nil?
的违规行为,也不会进行可能改变行为的更改。同样,当 IncludeSemanticChanges
设置为 false
且 Style/NilComparison
cop 的 EnforcedStyle: comparison
时,此 cop 不会报告 x != nil
的违规行为,也不会对 !x.nil?
样式进行更改。
当 IncludeSemanticChanges
设置为 true
时,此 cop 会报告 !x.nil?
的违规行为,并自动更正 !x.nil?
和 x != nil
为 x
,这通常是可以的,但可能会改变行为。
Style/Not
Style/NumberedParameters
Style/NumberedParametersLimit
Style/NumericLiteralPrefix
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.41 |
- |
检查八进制、十六进制、二进制和十进制字面量是否使用大写前缀,并将其更正为小写前缀或无前缀(十进制情况下)。
Style/NumericLiterals
Style/NumericPredicate
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.42 |
0.59 |
检查是否使用比较运算符(==
、>
、<
)来测试数字是否为零、正数或负数。这些可以使用它们各自的谓词方法替换。此 cop 也可以配置为执行相反的操作。
此检查器可以使用 AllowedMethods
自定义允许的方法。默认情况下,没有允许的方法。
此 cop 忽略#nonzero?
,因为它的值是真值或假值,而不是true
和false
,因此并不总是可以与!= 0
互换。
此 cop 允许与全局变量进行比较,因为它们通常填充了可以与整数比较的对象,但它们本身不是Integer
多态的。
示例
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
Style/ObjectThen
Style/OneLineConditional
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
0.90 |
检查单行上的 if/then/else/end 结构的使用。AlwaysCorrectToMultiline 配置选项可以设置为 true 以自动将所有违规转换为多行结构。当 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
Style/OperatorMethodCall
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
Always |
1.37 |
- |
检查运算符方法调用之前的冗余点。目标运算符方法是|
、^
、&
、<⇒
、==
、===
、=~
、>
、>=
、<
、⇐
、<<
、>>
、+
、-
、、
/
、%
、*
、~
、!
、!=
和 !~
。
Style/OptionHash
Style/OptionalArguments
Style/OptionalBooleanParameter
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
否 |
0.89 |
- |
检查在定义方法时可以使用关键字参数代替布尔参数的地方。默认情况下允许 respond_to_missing?
方法。这些可以通过 AllowedMethods
选项自定义。
Style/OrAssignment
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.50 |
- |
检查潜在的 ||=
运算符用法。
Style/ParallelAssignment
Style/ParenthesesAroundCondition
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
0.56 |
检查 if/unless/while/until 条件中是否存在多余的括号。
AllowSafeAssignment
选项用于安全赋值。安全赋值是指在赋值周围加上括号,表示“我知道我正在使用赋值作为条件,这不是错误”。
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)
Style/PercentQLiterals
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.25 |
- |
检查使用 %Q() 语法时是否可以使用 %q()。
Style/PerlBackrefs
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.13 |
- |
查找使用 Perl 风格的正则表达式匹配反向引用及其英文版本,如 $1、$2、$&、&+、$MATCH、$PREMATCH 等。
Style/PreferredHashMethods
Style/QuotedSymbols
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
Always |
1.16 |
- |
检查用于引号符号的引号是否与配置的默认值匹配。默认情况下使用与 Style/StringLiterals
相同的配置;如果该 cop 未启用,则默认 EnforcedStyle
为 single_quotes
。
字符串插值始终保持在双引号中。
注意:Lint/SymbolConversion
可以与之并行使用,以确保不需要引号的符号没有被引号括起来。此 cop 用于配置对需要引号的符号使用的引号样式。
Style/RaiseArgs
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.14 |
1.61 |
检查传递给 fail
和 raise
的参数。对于展开样式(默认),建议将异常类和消息传递给 raise
,而不是构造错误实例。它仍然允许只传递消息,或使用多个参数构造错误。
爆炸式风格的工作方式完全相同,但增加了当异常传递多个参数时,它还会建议构建错误对象。
爆炸式风格有一个AllowedCompactTypes
配置选项,它接受一个包含异常名称字符串的数组。
示例
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'
Style/RandomWithOffset
Style/RedundantArgument
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.4 |
1.55 |
检查传递给某些方法的冗余参数。
这个 cop 仅限于具有单个参数的方法。 |
方法名称及其冗余参数可以像这样配置
Methods:
join: ''
sum: 0
split: ' '
chomp: "\n"
chomp!: "\n"
foo: 2
安全
这个 cop 不安全,因为有以下限制
-
这个 cop 仅通过方法名称匹配,因此无法区分不同类中具有相同名称的方法。
-
如果设置了某些特殊的全局变量(例如
$;
、$/
),这个 cop 可能会不安全。当然,这取决于目标方法的性质。例如,join 的默认参数是$OUTPUT_FIELD_SEPARATOR
(或$,
),而不是''
,如果更改了该全局变量,''
就不是冗余参数了。
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/RedundantConstantBase
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
Always |
1.40 |
- |
避免在常量上使用冗余的 ::
前缀。
Ruby 搜索常量的方式有点复杂,从代码中很难理解 ::
是否是故意的。当 Module.nesting
为空时,不需要添加 ::
前缀,因此最好始终避免这种无意义的 ::
前缀,以避免混淆。
如果启用了 Lint/ConstantResolution 规则,则此规则将被禁用,以防止规则冲突。因为它尊重用户配置,这些配置希望启用默认情况下禁用的 Lint/ConstantResolution 规则。
|
Style/RedundantEach
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.38 |
- |
检查是否使用了冗余的 each
。
示例
# 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
。
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' ,但在禁用时不会检测到。
|
Style/RedundantFileExtensionInRequire
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.88 |
- |
检查 require
和 require_relative
提供的文件名中是否存在多余的 .rb
扩展名。
注意:如果省略扩展名,Ruby 会尝试在名称中添加 .rb
、.so
等,直到找到为止。如果找不到名为的文件,将引发 LoadError
。存在一个边缘情况,如果 foo.so
文件存在,则会加载 foo.so
文件而不是 LoadError
,当 require 'foo.rb'
将更改为 require 'foo'
时,但这似乎无害。
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?)
Style/RedundantInitialize
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
仅命令行(不安全) |
1.27 |
1.61 |
检查冗余的 initialize
方法。
如果初始化器什么也不做,或者只调用 super
并传递与传递给它的参数相同的参数,则初始化器是冗余的。如果初始化器接受一个可以接受多个值的参数(restarg
、kwrestarg
等),则不会注册违规,因为它允许初始化器接受与它的超类可能不同的参数数量。
如果初始化器参数具有默认值,RuboCop 假设它 **不** 是冗余的。 |
空初始化器被注册为违规,但可以有意创建空 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
Style/RedundantInterpolation
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.76 |
1.30 |
检查仅为插值表达式的字符串。
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/RedundantPercentQ
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/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
Style/RedundantSelf
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.10 |
0.13 |
检查冗余的 self
使用。
仅在以下情况下需要使用 self
-
在存在与参数或局部变量冲突的方法名称的情况下,向同一对象发送零参数的消息。
-
调用属性写入器以防止局部变量赋值。
注意,使用显式 self,您只能发送具有公共或受保护范围的消息,您无法以这种方式发送私有消息。
注意,我们允许在运算符中使用 self
,因为否则会很尴尬。还允许在块中使用 self.it
而不带参数,例如 0.times { self.it }
,遵循 Lint/ItWithoutArgumentsInBlock
规则。
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/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
Style/RequireOrder
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
始终(不安全) |
1.40 |
- |
按字母顺序排序require
和require_relative
。
示例
# 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
,修饰符形式的救援将处理异常。
Style/RescueStandardError
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.52 |
- |
检查救援StandardError
。支持两种风格implicit
和explicit
。如果指定了除StandardError
以外的任何错误,此 cop 不会注册违规。
Style/ReturnNil
Style/ReturnNilInPredicateMethodDefinition
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
Style/Sample
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.30 |
- |
识别shuffle.first
、shuffle.last
和shuffle[]
的用法,并将它们更改为使用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
匹配计算可枚举子集(数组、范围、集合等;见下文说明)的位置,并建议使用grep
或grep_v
代替。
哈希在使用grep 时不会像预期那样工作,这意味着hash.grep 不等于hash.select 。尽管 RuboCop 受限于静态分析,但此 cop 尝试在接收者为哈希(哈希文字、Hash.new 、Hash#[] 或to_h /to_hash )时避免注册违规。
|
在 Ruby 3.0 中,当不使用块时,grep 和grep_v 进行了优化,但在之前的版本中可能速度较慢。请参阅https://bugs.ruby-lang.org/issues/17030
|
安全性
自动更正被标记为不安全,因为grep
不会创建MatchData
,但之前可能在match?
或=~
调用后依赖它。
此外,cop 无法通过静态分析保证select
或reject
的接收者实际上是数组,因此更正可能并不完全等效。
示例
# 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/Semicolon
Style/SendWithLiteralMethodName
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.64 |
- |
检测使用带有字面方法名参数的 public_send
方法。由于 send
方法可以用来调用私有方法,默认情况下,只检测 public_send
方法。
Style/SignalException
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.11 |
0.37 |
检查 fail
和 raise
的使用。
示例
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
Style/SingleArgumentDig
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.89 |
- |
有时使用 dig
方法最终只使用一个参数。在这种情况下,应该用 []
替换 dig。
由于将 hash&.dig(:key)
替换为 hash[:key]
可能导致错误,因此将忽略使用安全导航调用 dig
方法。
Style/SingleLineBlockParams
Style/SingleLineDoEndBlock
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
Always |
1.57 |
- |
检查单行 do
…end
块。
在实践中,当 Style/BlockDelimiters
中的 EnforcedStyle: semantic
时,单行 do
…end
会自动更正。自动更正会保留 do
… end
语法以保留语义,不会将其更改为 {
…}
块。
Style/SingleLineMethods
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
1.8 |
检查包含主体的一行方法定义。它将接受没有主体的单行方法。
Ruby 3.0 中添加的无限方法也为此 cop 接受。
如果 Style/EndlessMethod
启用了 EnforcedStyle: allow_single_line
或 allow_always
,如果主体中只有一条语句,则单行方法将自动更正为无限方法。
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..-1
和 x..
仅保证对于 Array#[]
、String#[]
等效,而 cop 无法确定接收者的类。
例如
sum = proc { |ary| ary.sum }
sum[-3..-1] # => -6
sum[-3..] # Hangs forever
Style/SoleNestedConditional
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.89 |
1.5 |
如果条件分支仅包含一个条件节点,则可以将其条件与外部分支的条件合并。这有助于防止嵌套级别过深。
Style/SpecialGlobalVars
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.13 |
0.36 |
查找 Perl 风格的全局变量的使用。如果通过 RequireEnglish 配置启用,则更正为 'English' 库中的全局变量将向文件顶部添加 require 语句。
示例
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 $*
Style/StabbyLambdaParentheses
Style/StaticClass
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
否 |
始终(不安全) |
1.3 |
- |
检查只有类方法的类可以被模块替换的地方。类应该只在需要创建实例时使用。
示例
# 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
来轻松禁用的优点。
Style/StringChars
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
始终(不安全) |
1.12 |
- |
检查使用空字符串或正则表达式字面量参数的 String#split
的情况。
Style/StringConcatenation
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.89 |
1.18 |
检查可以使用字符串插值替换字符串连接的地方。
cop 可以自动更正简单的情况,但会跳过自动更正更复杂的情况,因为生成的代码将更难阅读。在这些情况下,将语句提取到局部变量或方法中可能会有用,然后你可以在字符串中插值它们。
当两个字符串之间的连接跨越多行时,此 cop 不会注册违规;相反,如果启用,Style/LineEndConcatenation 将拾取违规。
|
支持两种模式:1. aggressive
风格检查并更正所有 +
的出现,其中 +
的左侧或右侧是字符串字面量。2. 另一方面,conservative
风格仅在左侧(+
方法调用的接收器)是字符串字面量时检查和更正。当接收器是返回字符串的某些表达式(如 Pathname
)而不是字符串字面量时,这很有用。
示例
模式: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'
Style/StringLiterals
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
0.36 |
检查引号的使用是否符合配置的偏好。
示例
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"}/
Style/StructInheritance
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
是一个关键字,它与用于方法调用的关键字不同。
Style/SymbolArray
所需 Ruby 版本:2.0 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
0.49 |
检查由符号组成的数组字面量是否使用 %i() 语法。
或者,它检查使用 %i() 语法的符号数组,这些数组在不希望使用该语法的项目中,可能是因为它们支持低于 2.0 的 Ruby 版本。
配置选项:MinSize 如果设置,则元素数量少于此值的数组不会触发 cop。例如,MinSize
为 3
将不会对元素数量为 2 或更少的数组强制执行样式。
Style/SymbolProc
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.26 |
1.64 |
尽可能使用符号作为 proc。
如果您更喜欢允许带参数的方法使用块的样式,请将 AllowMethodsWithArguments
设置为 true
。define_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)
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
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
Style/TopLevelMethodDefinition
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
否 |
1.15 |
- |
Ruby 应用程序的新手可能会编写顶层方法,而理想情况下,它们应该在适当的类或模块中组织。此 cop 会查找顶层方法的定义并发出警告。
但是,对于 ruby 脚本,使用顶层方法是完全可以的。因此,此 cop 默认情况下处于禁用状态。
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,
)
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,
]
Style/TrailingCommaInBlockArgs
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
否 |
始终(不安全) |
0.81 |
- |
检查块参数中是否需要尾部逗号。只有一个参数且带尾部逗号的块需要该逗号。具有多个参数的块永远不需要尾部逗号。
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,
}
Style/TrailingUnderscoreVariable
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.31 |
0.35 |
检查变量赋值中是否有额外的下划线。
Style/TrivialAccessors
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
Always |
0.9 |
1.15 |
查找可以使用 attr_* 函数族自动创建的琐碎读写器方法。默认情况下,允许 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
方法。这些方法可以使用 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
Style/UnlessElse
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?
Style/VariableInterpolation
Style/WhenThen
Style/WhileUntilDo
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。例如,MinSize
为 3
将不会对元素数量为 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']
]
Style/YAMLFileRead
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
Always |
1.53 |
- |
检查使用YAML.load
、YAML.safe_load
和YAML.parse
以及File.read
参数。
YAML.safe_load_file 是在 Ruby 3.0 中引入的。
|
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
Style/YodaExpression
Style/ZeroLengthPredicate
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.37 |
0.39 |
检查可以被谓词方法替换的数字比较,例如 receiver.length == 0
、receiver.length > 0
和 receiver.length != 0
、receiver.length < 1
和 receiver.size == 0
,它们可以被 receiver.empty?
和 !receiver.empty?
替换。
File 、Tempfile 和 StringIO 没有 empty? ,因此允许 size == 0 和 size.zero? 。
|