Lint
Lint/AmbiguousBlockAssociation
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.48 |
1.13 |
检查在没有括号的情况下传递参数时,方法的不明确块关联。
此 cop 可以使用 AllowedMethods
自定义允许的方法。默认情况下,没有允许的方法。
示例
# bad
some_method a { |val| puts val }
# good
# With parentheses, there's no ambiguity.
some_method(a { |val| puts val })
# or (different meaning)
some_method(a) { |val| puts val }
# good
# Operator methods require no disambiguation
foo == bar { |b| b.baz }
# good
# Lambda arguments require no disambiguation
foo = ->(bar) { bar.baz }
Lint/AmbiguousOperator
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.17 |
0.83 |
检查在没有括号的情况下,方法调用第一个参数中的不明确运算符。
Lint/AmbiguousOperatorPrecedence
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终 |
1.21 |
- |
查找包含多个二元运算符的表达式,其中由于缺少括号,优先级不明确。例如,在 1 + 2 * 3
中,乘法将在加法之前发生,但从词法上看,加法似乎会先发生。
此 cop 不考虑一元运算符(即 !a
或 -b
)或比较运算符(即 a =~ b
),因为它们并不不明确。
范围由 Lint/AmbiguousRange 处理。
|
Lint/AmbiguousRange
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终(不安全) |
1.19 |
- |
检查不明确的范围。
范围的优先级很低,这会导致在将范围与其他运算符一起使用时出现意外行为。此 cop 通过要求在复杂的范围边界(任何不是字面量的内容:数字、字符串、符号等)周围使用括号来避免这种情况。
此 cop 可以使用 RequireParenthesesForMethodChains
进行配置,以指定此 cop 是否应该将方法链(包括 self.foo
)括在括号中。
无论配置如何,如果方法接收者是基本字面量值,它将被包装以防止1..2.to_a 的歧义。
|
Lint/AmbiguousRegexpLiteral
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.17 |
0.83 |
检查在没有括号的情况下,方法调用第一个参数中是否有歧义的正则表达式字面量。
Lint/AssignmentInCondition
Lint/BinaryOperatorWithIdenticalOperands
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
否 |
0.89 |
1.7 |
检查二元运算符具有相同操作数的地方。
它涵盖算术运算符:-
、/
、%
;比较运算符:==
、===
、=~
、>
、>=
、<
、⇐
;按位运算符:|
、^
、&
;布尔运算符:&&
、||
和“宇宙飞船”运算符 - <⇒
。
此 cop 允许简单的算术运算:+
、、
*
、<<
和 >>
。虽然这些可以以不同的方式重写,但没有必要这样做。这并不包括诸如 -
或 /
之类的运算,因为结果始终相同(x - x
始终为 0;x / x
始终为 1),因此是合法的违规行为。
Lint/CircularArgumentReference
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.33 |
- |
检查可选关键字参数和可选序数参数中的循环参数引用。
此 cop 镜像了 MRI 自 2.2 版本以来的警告。
示例
# bad
def bake(pie: pie)
pie.heat_up
end
# good
def bake(pie:)
pie.refrigerate
end
# good
def bake(pie: self.pie)
pie.feed_to(user)
end
# bad
def cook(dry_ingredients = dry_ingredients)
dry_ingredients.reduce(&:+)
end
# good
def cook(dry_ingredients = self.dry_ingredients)
dry_ingredients.combine
end
Lint/ConstantDefinitionInBlock
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.91 |
1.3 |
不要在块内定义常量,因为块的范围不会以任何方式隔离或命名空间常量。
如果您尝试定义一次常量,请在块之外定义它,或者如果在外部范围内定义常量会造成问题,请使用变量或方法。
对于元编程,请使用 const_set
。
示例
# bad
task :lint do
FILES_TO_LINT = Dir['lib/*.rb']
end
# bad
describe 'making a request' do
class TestRequest; end
end
# bad
module M
extend ActiveSupport::Concern
included do
LIST = []
end
end
# good
task :lint do
files_to_lint = Dir['lib/*.rb']
end
# good
describe 'making a request' do
let(:test_request) { Class.new }
# see also `stub_const` for RSpec
end
# good
module M
extend ActiveSupport::Concern
included do
const_set(:LIST, [])
end
end
Lint/ConstantResolution
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
否 |
0.86 |
- |
检查某些常量是否完全限定。
默认情况下不启用此功能,因为它会不必要地标记许多违规行为。
通常,宝石应该完全限定所有常量,以避免与使用宝石的代码发生冲突。启用此 cop 而不使用Only
/Ignore
大型项目随着时间的推移最终会遇到一两个常量名称,这些名称由于与库的冲突或只是在内部使用相同的名称作为命名空间和类而出现问题。为了避免太多不必要的违规,请使用Only: [The, Constant, Names, Causing, Issues]
启用此 cop
如果启用了此 cop,则会禁用Style/RedundantConstantBase cop,以防止规则冲突。因为它尊重希望启用此 cop 的用户配置,而此 cop 默认情况下是禁用的。
|
Lint/Debugger
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.14 |
1.63 |
检查不应保留用于生产代码的调试调用(例如debugger
或binding.pry
)。
可以使用DebuggerMethods
配置 cop。默认情况下,配置了许多宝石调试入口点(Kernel
、Byebug
、Capybara
、debug.rb
、Pry
、Rails
、RubyJard
和WebConsole
)。可以添加其他方法。
如果需要,可以禁用特定的默认组
Lint/Debugger:
DebuggerMethods:
WebConsole: ~
您还可以通过添加一个新类别来添加自己的方法
Lint/Debugger:
DebuggerMethods:
MyDebugger:
MyDebugger.debug_this
某些宝石还附带一些文件,这些文件在需要时会启动调试会话,例如ruby/debug
中的require 'debug/start'
。这些要求可以通过DebuggerRequires
进行配置。它与DebuggerMethods
具有相同的结构,您可以在上面阅读有关它的信息。
示例
# bad (ok during development)
# using pry
def some_method
binding.pry
do_something
end
# bad (ok during development)
# using byebug
def some_method
byebug
do_something
end
# good
def some_method
do_something
end
可配置属性
名称 | 默认值 | 可配置值 |
---|---|---|
DebuggerMethods |
|
|
DebuggerRequires |
|
Lint/DeprecatedClassMethods
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.19 |
- |
检查对已弃用的类方法使用的使用。
示例
# bad
File.exists?(some_path)
Dir.exists?(some_path)
iterator?
attr :name, true
attr :name, false
ENV.freeze # Calling `Env.freeze` raises `TypeError` since Ruby 2.7.
ENV.clone
ENV.dup # Calling `Env.dup` raises `TypeError` since Ruby 3.1.
Socket.gethostbyname(host)
Socket.gethostbyaddr(host)
# good
File.exist?(some_path)
Dir.exist?(some_path)
block_given?
attr_accessor :name
attr_reader :name
ENV # `ENV.freeze` cannot prohibit changes to environment variables.
ENV.to_h
ENV.to_h # `ENV.dup` cannot dup `ENV`, use `ENV.to_h` to get a copy of `ENV` as a hash.
Addrinfo.getaddrinfo(nodename, service)
Addrinfo.tcp(host, port).getnameinfo
Lint/DeprecatedConstants
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终 |
1.8 |
1.40 |
检查过时的常量。
它具有 DeprecatedConstants
配置。如果存在替代方法,可以将替代值设置为 Alternative
。还可以将过时版本设置为 DeprecatedVersion
。如果不需要,可以省略这些选项。
DeprecatedConstants: 'DEPRECATED_CONSTANT': Alternative: 'alternative_value' DeprecatedVersion: 'deprecated_version'
默认情况下,NIL
、TRUE
、FALSE
、Net::HTTPServerException
、Random::DEFAULT
、Struct::Group
和 Struct::Passwd
已配置。
示例
# bad
NIL
TRUE
FALSE
Net::HTTPServerException
Random::DEFAULT # Return value of Ruby 2 is `Random` instance, Ruby 3.0 is `Random` class.
Struct::Group
Struct::Passwd
# good
nil
true
false
Net::HTTPClientException
Random.new # `::DEFAULT` has been deprecated in Ruby 3, `.new` is compatible with Ruby 2.
Etc::Group
Etc::Passwd
可配置属性
名称 | 默认值 | 可配置值 |
---|---|---|
DeprecatedConstants |
|
Lint/DeprecatedOpenSSLConstant
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.84 |
- |
自 OpenSSL 版本 2.2.0 起,OpenSSL::Cipher
和 OpenSSL::Digest
的算法常量已过时。建议改为传递字符串。
示例
# Example for OpenSSL::Cipher instantiation.
# bad
OpenSSL::Cipher::AES.new(128, :GCM)
# good
OpenSSL::Cipher.new('aes-128-gcm')
# Example for OpenSSL::Digest instantiation.
# bad
OpenSSL::Digest::SHA256.new
# good
OpenSSL::Digest.new('SHA256')
# Example for ::Digest inherited class methods.
# bad
OpenSSL::Digest::SHA256.digest('foo')
# good
OpenSSL::Digest.digest('SHA256', 'foo')
Lint/DisjunctiveAssignmentInConstructor
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.62 |
0.88 |
检查构造函数中应为普通赋值的析取赋值 (||=
)。
到目前为止,此 cop 仅关注实例变量的析取赋值。
在 Ruby 中,实例变量在赋值之前为 nil,因此析取是不必要的。普通赋值具有相同的效果。
Lint/DuplicateBranch
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.3 |
1.7 |
检查 if/unless
、case-when
、case-in
和 rescue
结构中是否存在重复的代码块。
当 IgnoreLiteralBranches: true
时,如果分支返回基本字面值(字符串、符号、整数、浮点数、有理数、复数、true
、false
或 nil
),或者返回仅包含上述基本字面值的数组、哈希、正则表达式或范围,则不会将这些分支注册为违规。
当 IgnoreConstantBranches: true
时,如果分支返回常量值,则不会将这些分支注册为违规。
示例
# bad
if foo
do_foo
do_something_else
elsif bar
do_foo
do_something_else
end
# good
if foo || bar
do_foo
do_something_else
end
# bad
case x
when foo
do_foo
when bar
do_foo
else
do_something_else
end
# good
case x
when foo, bar
do_foo
else
do_something_else
end
# bad
begin
do_something
rescue FooError
handle_error
rescue BarError
handle_error
end
# good
begin
do_something
rescue FooError, BarError
handle_error
end
Lint/DuplicateMatchPattern
所需的 Ruby 版本:2.7 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.50 |
- |
检查 in
关键字中是否使用重复的模式。
示例
# bad
case x
in 'first'
do_something
in 'first'
do_something_else
end
# good
case x
in 'first'
do_something
in 'second'
do_something_else
end
# bad - repeated alternate patterns with the same conditions don't depend on the order
case x
in foo | bar
first_method
in bar | foo
second_method
end
# good
case x
in foo | bar
first_method
in bar | baz
second_method
end
# bad - repeated hash patterns with the same conditions don't depend on the order
case x
in foo: a, bar: b
first_method
in bar: b, foo: a
second_method
end
# good
case x
in foo: a, bar: b
first_method
in bar: b, baz: c
second_method
end
# bad - repeated array patterns with elements in the same order
case x
in [foo, bar]
first_method
in [foo, bar]
second_method
end
# good
case x
in [foo, bar]
first_method
in [bar, foo]
second_method
end
# bad - repeated the same patterns and guard conditions
case x
in foo if bar
first_method
in foo if bar
second_method
end
# good
case x
in foo if bar
first_method
in foo if baz
second_method
end
Lint/ElseLayout
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.17 |
1.2 |
检查奇数 else
块布局 - 例如在 else
关键字的同一行上有一个表达式,这通常是一个错误。
它的自动更正调整布局以保持语法。因此,这种自动更正与错误情况语法的兼容更正,但如果您的代码在 elsif
和 else
中犯了错误,您将不得不手动更正。
示例
# bad
if something
# ...
else do_this
do_that
end
# good
# This code is compatible with the bad case. It will be autocorrected like this.
if something
# ...
else
do_this
do_that
end
# This code is incompatible with the bad case.
# If `do_this` is a condition, `elsif` should be used instead of `else`.
if something
# ...
elsif do_this
do_that
end
Lint/EmptyBlock
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.1 |
1.15 |
检查没有主体块。这种空块通常是疏忽,或者我们应该提供注释以阐明我们的目标。
默认情况下,忽略空 lambda 和 proc。
为了向后兼容,允许/禁止空 lambda 和 proc 的配置称为 AllowEmptyLambdas ,即使它也适用于 proc。
|
示例
# bad
items.each { |item| }
# good
items.each { |item| puts item }
AllowComments: true(默认)
# good
items.each do |item|
# TODO: implement later (inner comment)
end
items.each { |item| } # TODO: implement later (inline comment)
AllowComments: false
# bad
items.each do |item|
# TODO: implement later (inner comment)
end
items.each { |item| } # TODO: implement later (inline comment)
Lint/EmptyClass
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.3 |
- |
检查没有主体的类和元类。这种空类和元类通常是疏忽,或者我们应该提供注释以更清楚地说明我们的目标。
示例
# bad
class Foo
end
class Bar
class << self
end
end
class << obj
end
# good
class Foo
def do_something
# ... code
end
end
class Bar
class << self
attr_reader :bar
end
end
class << obj
attr_reader :bar
end
Lint/EmptyConditionalBody
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
仅命令行(不安全) |
0.89 |
1.61 |
检查 if
、elsif
和 unless
分支是否存在没有主体。
空 else 分支由 Style/EmptyElse 处理。
|
Lint/EmptyInPattern
Lint/EmptyWhen
Lint/EnsureReturn
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.9 |
0.83 |
检查 ensure
块中的 return
。从 ensure
块返回 return
是一个危险的代码气味,因为它将优先于任何被抛出的异常,并且异常将被静默丢弃,就好像它被拯救了一样。
如果你想拯救一些(或所有)异常,最好明确地这样做
Lint/ErbNewArguments
必需的 Ruby 版本:2.6 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.56 |
- |
模拟 Ruby 2.6 中的以下 Ruby 警告。
$ cat example.rb
ERB.new('hi', nil, '-', '@output_buffer')
$ ruby -rerb example.rb
example.rb:1: warning: Passing safe_level with the 2nd argument of ERB.new is
deprecated. Do not use it, and specify other arguments as keyword arguments.
example.rb:1: warning: Passing trim_mode with the 3rd argument of ERB.new is
deprecated. Use keyword argument like ERB.new(str, trim_mode:...) instead.
example.rb:1: warning: Passing eoutvar with the 4th argument of ERB.new is
deprecated. Use keyword argument like ERB.new(str, eoutvar: ...) instead.
现在除了第一个以外的非关键字参数被软弃用,并且将在 Ruby 2.5 成为 EOL 时被删除。自 ERB 2.2.0 起,使用非关键字参数的 ERB.new
已弃用。使用 :trim_mode
和 :eoutvar
关键字参数到 ERB.new
。此 cop 识别 ERB.new(str, trim_mode, eoutvar)
可以被 ERB.new(str, :trim_mode: trim_mode, eoutvar: eoutvar)
替换的地方。
示例
# Target codes supports Ruby 2.6 and higher only
# bad
ERB.new(str, nil, '-', '@output_buffer')
# good
ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')
# Target codes supports Ruby 2.5 and lower only
# good
ERB.new(str, nil, '-', '@output_buffer')
# Target codes supports Ruby 2.6, 2.5 and lower
# bad
ERB.new(str, nil, '-', '@output_buffer')
# good
# Ruby standard library style
# https://github.com/ruby/ruby/commit/3406c5d
if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')
else
ERB.new(str, nil, '-', '@output_buffer')
end
# good
# Use `RUBY_VERSION` style
if RUBY_VERSION >= '2.6'
ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')
else
ERB.new(str, nil, '-', '@output_buffer')
end
Lint/FlipFlop
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.16 |
- |
根据 Ruby 风格指南查找使用翻转操作符的情况。
以下是 Ruby 中翻转操作符的历史。翻转操作符在 Ruby 2.6.0 中已弃用,但该弃用在 Ruby 2.7.0 中已恢复,并已移植到 Ruby 2.6。参见:https://bugs.ruby-lang.org/issues/5400
Lint/FloatComparison
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.89 |
- |
检查是否存在对浮点数进行精确比较。
浮点数本身是不精确的,对它们进行精确相等比较几乎永远不是想要的语义。通过 ==/!=
运算符进行比较会检查浮点数表示是否完全相同,如果您执行任何涉及精度损失的算术运算,这非常不可能。
# good - comparing against zero x == 0.0 x != 0.0
# good (x - 0.1).abs < Float::EPSILON
# good tolerance = 0.0001 (x - 0.1).abs < tolerance
# Or some other epsilon based type of comparison: # https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/
Lint/FormatParameterMismatch
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.33 |
- |
此 lint 检查 format/sprintf/#% 的预期字段数量与实际传递的参数数量是否匹配。
此外,它还会检查同一个格式字符串中是否使用了不同的格式。不要在同一个格式字符串中混合使用编号、未编号和命名格式。
Lint/HashCompareByIdentity
Lint/HeredocMethodCallPosition
Lint/IdentityComparison
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.91 |
- |
在比较 object_id
时,优先使用 equal?
而不是 ==
。
Object#equal?
用于比较对象的标识,而 Object#==
用于进行值比较。
Lint/IncompatibleIoSelectWithFiberScheduler
Lint/IneffectiveAccessModifier
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.36 |
- |
检查应用于单例方法的 private
或 protected
访问修饰符。这些访问修饰符不会使单例方法变为私有/受保护。private_class_method
可用于此目的。
Lint/InheritException
Lint/ItWithoutArgumentsInBlock
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.59 |
- |
模拟 Ruby 3.3 中的以下 Ruby 警告。
$ ruby -e '0.times { it }'
-e:1: warning: `it` calls without arguments will refer to the first block param in Ruby 3.4;
use it() or self.it
在 Ruby 3.4 中,没有参数的 it
调用将引用第一个块参数。因此,请使用 it()
或 self.it
来确保兼容性。
Lint/LambdaWithoutLiteralBlock
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终 |
1.8 |
- |
检查没有字面块的 lambda 的使用情况。它模拟 Ruby 3.0 中的以下警告
$ ruby -vwe 'lambda(&proc {})' ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19] -e:1: warning: lambda without a literal block is deprecated; use the proc without lambda instead
这样,proc 对象永远不会转换为 lambda。自动更正用兼容的 proc 参数替换。
Lint/LiteralAsCondition
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.51 |
- |
检查用作条件的字面量或用作 and/or 表达式中的操作数,这些表达式用作 if/while/until/case-when/case-in 的条件。
在 case-in 条件中,匹配变量在 in 中使用时,字面量被接受为模式匹配。
|
Lint/LiteralAssignmentInCondition
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.58 |
- |
检查 if
、while
和 until
条件中的字面量赋值。它模拟以下 Ruby 警告
$ ruby -we 'if x = true; end'
-e:1: warning: found `= literal' in conditional, should be ==
作为 lint cop,无法确定 ==
是否是预期的,因此此 cop 不提供自动更正。
Lint/Loop
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.9 |
1.3 |
检查 begin…end while/until something
的使用情况。
Lint/MissingCopEnableDirective
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.52 |
- |
检查 # rubocop:disable …
语句之后是否存在 # rubocop:enable …
语句。这将防止在代码的较宽范围内保留 cop 禁用,而这些禁用可能是后来贡献者不知道的。
示例
# Lint/MissingCopEnableDirective:
# MaximumRangeSize: .inf
# good
# rubocop:disable Layout/SpaceAroundOperators
x= 0
# rubocop:enable Layout/SpaceAroundOperators
# y = 1
# EOF
# bad
# rubocop:disable Layout/SpaceAroundOperators
x= 0
# EOF
# Lint/MissingCopEnableDirective:
# MaximumRangeSize: 2
# good
# rubocop:disable Layout/SpaceAroundOperators
x= 0
# With the previous, there are 2 lines on which cop is disabled.
# rubocop:enable Layout/SpaceAroundOperators
# bad
# rubocop:disable Layout/SpaceAroundOperators
x= 0
x += 1
# Including this, that's 3 lines on which the cop is disabled.
# rubocop:enable Layout/SpaceAroundOperators
Lint/MissingSuper
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.89 |
1.4 |
检查构造函数和生命周期回调中是否存在没有调用 super
的情况。
该 cop 不考虑 method_missing
(和 respond_to_missing?
),因为在某些情况下,覆盖被认为是缺失的方法是有意义的。在其他情况下,理论上的理想处理方式可能很困难或冗长,而没有实际收益。
不支持自动更正,因为无法自动确定 super
的位置。
Object
和 BasicObject
被该 cop 允许,因为它们是无状态的。但是,有时你可能希望允许该 cop 从其他父类中允许,例如在抽象类的情况下,该类不打算使用 super
调用。在这些情况下,你可以使用 AllowedParentClasses
选项来指定除了 Object
和 BasicObject
之外还应该允许哪些类。
示例
# bad
class Employee < Person
def initialize(name, salary)
@salary = salary
end
end
# good
class Employee < Person
def initialize(name, salary)
super(name)
@salary = salary
end
end
# bad
Employee = Class.new(Person) do
def initialize(name, salary)
@salary = salary
end
end
# good
Employee = Class.new(Person) do
def initialize(name, salary)
super(name)
@salary = salary
end
end
# bad
class Parent
def self.inherited(base)
do_something
end
end
# good
class Parent
def self.inherited(base)
super
do_something
end
end
# good
class ClassWithNoParent
def initialize
do_something
end
end
Lint/MixedCaseRange
Lint/NestedMethodDefinition
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.32 |
- |
检查嵌套方法定义。
示例
# bad
# `bar` definition actually produces methods in the same scope
# as the outer `foo` method. Furthermore, the `bar` method
# will be redefined every time `foo` is invoked.
def foo
def bar
end
end
# good
def foo
bar = -> { puts 'hello' }
bar.call
end
# good
# `class_eval`, `instance_eval`, `module_eval`, `class_exec`, `instance_exec`, and
# `module_exec` blocks are allowed by default.
def foo
self.class.class_eval do
def bar
end
end
end
def foo
self.class.module_exec do
def bar
end
end
end
# good
def foo
class << self
def bar
end
end
end
AllowedMethods: [] (默认)
# bad
def do_something
has_many :articles do
def find_or_create_by_name(name)
end
end
end
Lint/NestedPercentLiteral
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.52 |
- |
检查嵌套百分比字面量。
示例
# bad
# The percent literal for nested_attributes is parsed as four tokens,
# yielding the array [:name, :content, :"%i[incorrectly", :"nested]"].
attributes = {
valid_attributes: %i[name content],
nested_attributes: %i[name content %i[incorrectly nested]]
}
# good
# Neither is incompatible with the bad case, but probably the intended code.
attributes = {
valid_attributes: %i[name content],
nested_attributes: [:name, :content, %i[incorrectly nested]]
}
attributes = {
valid_attributes: %i[name content],
nested_attributes: [:name, :content, [:incorrectly, :nested]]
}
Lint/NoReturnInBeginEndBlocks
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.2 |
- |
检查赋值上下文中 `begin..end` 块内是否存在 `return`。在这种情况下,`return` 将导致退出当前方法,可能导致意外行为。
示例
# bad
@some_variable ||= begin
return some_value if some_condition_is_met
do_something
end
# good
@some_variable ||= begin
if some_condition_is_met
some_value
else
do_something
end
end
# good
some_variable = if some_condition_is_met
return if another_condition_is_met
some_value
else
do_something
end
Lint/NonAtomicFileOperation
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终(不安全) |
1.31 |
- |
检查非原子文件操作。然后用几乎等效的原子方法替换它。
这些可能会导致难以重现的问题,尤其是在并行频繁的文件操作的情况下,例如使用 parallel_rspec 的测试运行。
例如:如果不存在则创建目录,存在以下问题
当目录在 exist?
时不存在,但有人在执行 mkdir
之前创建了它时,就会发生异常。
后续进程在没有该目录的情况下执行,而该目录应该在 exist?
时存在,但有人随后将其删除。
示例
# bad - race condition with another process may result in an error in `mkdir`
unless Dir.exist?(path)
FileUtils.mkdir(path)
end
# good - atomic and idempotent creation
FileUtils.mkdir_p(path)
# bad - race condition with another process may result in an error in `remove`
if File.exist?(path)
FileUtils.remove(path)
end
# good - atomic and idempotent removal
FileUtils.rm_f(path)
Lint/NonDeterministicRequireOrder
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.78 |
- |
Dir[…]
和 Dir.glob(…)
不保证返回文件的顺序。最终顺序由操作系统和文件系统决定。这意味着在顺序重要的情况下使用它们,例如需要文件,会导致难以调试的间歇性故障。为了确保这种情况不会发生,请始终对列表进行排序。
在 Ruby 3.0 中,Dir.glob
和 Dir[]
默认情况下会对 globbed 结果进行排序。因此,当使用 Ruby 3.0 或更高版本时,所有不良情况都是可以接受的。
当仅支持 Ruby 3.0 及更高版本时,此 cop 将被弃用并删除。 |
示例
# bad
Dir["./lib/**/*.rb"].each do |file|
require file
end
# good
Dir["./lib/**/*.rb"].sort.each do |file|
require file
end
# bad
Dir.glob(Rails.root.join(__dir__, 'test', '*.rb')) do |file|
require file
end
# good
Dir.glob(Rails.root.join(__dir__, 'test', '*.rb')).sort.each do |file|
require file
end
# bad
Dir['./lib/**/*.rb'].each(&method(:require))
# good
Dir['./lib/**/*.rb'].sort.each(&method(:require))
# bad
Dir.glob(Rails.root.join('test', '*.rb'), &method(:require))
# good
Dir.glob(Rails.root.join('test', '*.rb')).sort.each(&method(:require))
# good - Respect intent if `sort` keyword option is specified in Ruby 3.0 or higher.
Dir.glob(Rails.root.join(__dir__, 'test', '*.rb'), sort: false).each(&method(:require))
Lint/NonLocalExitFromIterator
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.30 |
- |
检查迭代器中没有返回值的非本地退出。它在以下情况下注册违规
-
没有返回值,
-
块之前是方法链,
-
块有参数,
-
接收块的方法不是
define_method
或define_singleton_method
, -
返回值不在内部作用域中,例如 lambda 或方法定义。
示例
class ItemApi
rescue_from ValidationError do |e| # non-iteration block with arg
return { message: 'validation error' } unless e.errors # allowed
error_array = e.errors.map do |error| # block with method chain
return if error.suppress? # warned
return "#{error.param}: invalid" unless error.message # allowed
"#{error.param}: #{error.message}"
end
{ message: 'validation error', errors: error_array }
end
def update_items
transaction do # block without arguments
return unless update_necessary? # allowed
find_each do |item| # block without method chain
return if item.stock == 0 # false-negative...
item.update!(foobar: true)
end
end
end
end
Lint/NumberConversion
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
已禁用 |
是 |
始终(不安全) |
0.53 |
1.1 |
警告使用不安全的数字转换。如果自动类型转换失败,不安全的数字转换会导致意外错误。Cop 优先使用数字类进行解析。
使用 Integer
、Float
等进行转换,如果给定的输入不是数字(例如空字符串),则会引发 ArgumentError
,而 to_i
等则会尝试转换,无论输入是什么(''.to_i ⇒ 0
)。因此,此 cop 默认情况下处于禁用状态,因为它不一定是始终正确地引发异常,如果值不是数字。
某些值无法使用 Kernel 方法之一正确转换(例如,此 cop 默认情况下允许 Time 和 DateTime 值)。类似地,Rails 的持续时间方法与 Integer() 不兼容,可以使用 AllowedMethods 允许。默认情况下,没有允许的方法。
|
Lint/NumberedParameterAssignment
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.9 |
- |
检查对编号参数赋值的使用。它模拟了 Ruby 2.7 中的以下警告
$ ruby -ve '_1 = :value' ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19] -e:1: warning: `_1' is reserved for numbered parameter; consider another name
在 Ruby 3.0 中,对编号参数(从 _1
到 _9
)进行赋值会导致错误。
$ ruby -ve '_1 = :value' ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19] -e:1: _1 is reserved for numbered parameter
参数化的参数是从 _1 到 _9 。此 cop 检查 _0 ,以及超过 _10 ,以防止混淆。
|
Lint/OrderedMagicComments
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.53 |
1.37 |
检查魔术注释的正确顺序,以及魔术注释是否未放在 Shebang 之前。
示例
# bad
# frozen_string_literal: true
# encoding: ascii
p [''.frozen?, ''.encoding] #=> [true, #<Encoding:UTF-8>]
# good
# encoding: ascii
# frozen_string_literal: true
p [''.frozen?, ''.encoding] #=> [true, #<Encoding:US-ASCII>]
# good
#!/usr/bin/env ruby
# encoding: ascii
# frozen_string_literal: true
p [''.frozen?, ''.encoding] #=> [true, #<Encoding:US-ASCII>]
Lint/OutOfRangeRegexpRef
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
否 |
0.89 |
- |
查找超出范围的 Regexp 捕获的引用,因此始终返回 nil。
Lint/ParenthesesAsGroupedExpression
Lint/RaiseException
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.81 |
0.86 |
检查引发 Exception
类的 raise
或 fail
语句。
您可以使用 AllowedImplicitNamespaces
选项指定将作为隐式命名空间的模块名称。当省略命名空间时,cop 会对命名空间 Exception
产生误报。此选项可以通过指定要省略的 Exception
命名空间来防止误报。或者,使 Exception
成为具有显式命名空间的完全限定类名。
Lint/RedundantCopDisableDirective
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.76 |
- |
检测可以删除的rubocop:disable
注释实例,而不会导致任何违规被报告。它作为 cop 实现,因为它继承自 Cop 基类并调用 add_offense。其实现的非同寻常之处在于它没有任何 on_* 方法或 investigate 方法。这意味着它不参与其他 cop 执行工作的调查阶段。相反,它会等到在执行的后期阶段被调用。它不能作为普通 cop 实现的原因是,它依赖于所有其他 cop 的结果来完成工作。
Lint/RedundantCopEnableDirective
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.76 |
- |
检测可以删除的rubocop:enable
注释实例。
当注释一次启用所有 cop 时rubocop:enable all
,该 cop 会检查是否实际上启用了任何 cop。
Lint/RedundantDirGlobSort
所需 Ruby 版本:3.0 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终(不安全) |
1.8 |
1.26 |
在 Ruby 3.0 中默认对 globbed 结果进行排序。此 cop 检查对Dir.glob
和Dir[]
的冗余sort
方法。
Lint/RedundantRequireStatement
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终(不安全) |
0.76 |
1.57 |
检查不必要的 require
语句。
以下功能是不必要的 require
语句,因为它们已经加载。例如 Ruby 2.2
ruby -ve 'p $LOADED_FEATURES.reject { |feature| %r|/| =~ feature }' ruby 2.2.8p477 (2017-09-14 revision 59906) [x86_64-darwin13] ["enumerator.so", "rational.so", "complex.so", "thread.rb"]
以下是每个 TargetRubyVersion
目标的功能。
-
2.0+ …
enumerator
-
2.1+ …
thread
-
2.2+ … 在上面添加
rational
和complex
-
2.5+ … 在上面添加
pp
-
2.7+ … 在上面添加
ruby2_keywords
-
3.1+ … 在上面添加
fiber
-
3.2+ …
set
此 cop 针对这些功能。
Lint/RedundantSafeNavigation
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
始终(不安全) |
0.93 |
- |
检查冗余的安全导航调用。在类和模块中以驼峰命名法命名的常量为 nil
的用例很少见,并且当接收者为常量时不会检测到违规。检测也适用于文字接收者,除了 nil
。
对于所有接收者,默认情况下会检查 instance_of?
、kind_of?
、is_a?
、eql?
、respond_to?
和 equal?
方法。这些可以通过 AllowedMethods
选项进行自定义。
AllowedMethods
选项指定了空安全方法,换句话说,它是一种允许跳过安全导航的方法。请注意,AllowedMethod
选项不是指定要抑制(允许)此 cop 检查的方法的选项。
在下面的示例中,安全导航运算符 (&.
) 是不必要的,因为 NilClass
具有 respond_to?
和 is_a?
之类的方法。
示例
# bad
CamelCaseConst&.do_something
# bad
do_something if attrs&.respond_to?(:[])
# good
do_something if attrs.respond_to?(:[])
# bad
while node&.is_a?(BeginNode)
node = node.parent
end
# good
CamelCaseConst.do_something
# good
while node.is_a?(BeginNode)
node = node.parent
end
# good - without `&.` this will always return `true`
foo&.respond_to?(:to_a)
# bad - for `nil`s conversion methods return default values for the type
foo&.to_h || {}
foo&.to_h { |k, v| [k, v] } || {}
foo&.to_a || []
foo&.to_i || 0
foo&.to_f || 0.0
foo&.to_s || ''
# good
foo.to_h
foo.to_h { |k, v| [k, v] }
foo.to_a
foo.to_i
foo.to_f
foo.to_s
Lint/RedundantSplatExpansion
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.76 |
1.7 |
检查不必要的 splat 展开用法。
示例
# bad
a = *[1, 2, 3]
a = *'a'
a = *1
['a', 'b', *%w(c d e), 'f', 'g']
# good
c = [1, 2, 3]
a = *c
a, b = *c
a, *b = *c
a = *1..10
a = ['a']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
# bad
do_something(*['foo', 'bar', 'baz'])
# good
do_something('foo', 'bar', 'baz')
# bad
begin
foo
rescue *[StandardError, ApplicationError]
bar
end
# good
begin
foo
rescue StandardError, ApplicationError
bar
end
# bad
case foo
when *[1, 2, 3]
bar
else
baz
end
# good
case foo
when 1, 2, 3
bar
else
baz
end
Lint/RedundantStringCoercion
Lint/RefinementImportMethods
Lint/RequireRangeParentheses
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.32 |
- |
检查范围字面量在范围结束位于换行符时是否用括号括起来。
以下是可能用于 (42..) 的。但是,兼容的是 42..do_something 。因此,此 cop 不提供自动更正,因为它留给用户。
|
case condition
when 42..
do_something
end
Lint/RescueException
Lint/SafeNavigationChain
所需的 Ruby 版本:2.3 |
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.47 |
0.77 |
如果接收者为 nil,安全导航运算符将返回 nil。如果在安全导航运算符之后链接一个普通的函数调用,它将引发 NoMethodError。我们应该在安全导航运算符之后使用安全导航运算符。此 cop 检查上面概述的问题。
Lint/SafeNavigationConsistency
Lint/ScriptPermission
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.49 |
0.50 |
检查具有 shebang 行作为第一行的文件是否被授予执行权限。
示例
# bad
# A file which has a shebang line as its first line is not
# granted execute permission.
#!/usr/bin/env ruby
puts 'hello, world'
# good
# A file which has a shebang line as its first line is
# granted execute permission.
#!/usr/bin/env ruby
puts 'hello, world'
# good
# A file which has not a shebang line as its first line is not
# granted execute permission.
puts 'hello, world'
Lint/SendWithMixinArgument
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.75 |
- |
在使用 mix-in 时,检查 send
、public_send
和 send
方法。
include
和 prepend
方法在 Ruby 2.0 之前是私有方法,它们通过 send
方法混合进来。此 cop 使用 Ruby 2.1 或更高版本风格,可以通过公共方法调用。最初是公共方法的 extend
方法也针对风格统一进行了处理。
示例
# bad
Foo.send(:include, Bar)
Foo.send(:prepend, Bar)
Foo.send(:extend, Bar)
# bad
Foo.public_send(:include, Bar)
Foo.public_send(:prepend, Bar)
Foo.public_send(:extend, Bar)
# bad
Foo.__send__(:include, Bar)
Foo.__send__(:prepend, Bar)
Foo.__send__(:extend, Bar)
# good
Foo.include Bar
Foo.prepend Bar
Foo.extend Bar
Lint/ShadowedArgument
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.52 |
- |
检查被遮蔽的参数。
此 cop 有 IgnoreImplicitReferences
配置选项。这意味着当 IgnoreImplicitReferences
为 true
时,为了将参数传递给零元 super
,会使用参数遮蔽。
示例
# bad
do_something do |foo|
foo = 42
puts foo
end
def do_something(foo)
foo = 42
puts foo
end
# good
do_something do |foo|
foo = foo + 42
puts foo
end
def do_something(foo)
foo = foo + 42
puts foo
end
def do_something(foo)
puts foo
end
Lint/ShadowedException
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.41 |
- |
检查被遮蔽的异常,该异常被一个不太具体的异常在更具体的异常被救援之前救援。
如果一个异常在它的祖先之后被救援,或者它和它的祖先都在同一个 rescue
语句中被救援,那么它就被认为是被遮蔽的。在这两种情况下,更具体的救援都是不必要的,因为它被救援不太具体的异常所覆盖。(例如,rescue Exception, StandardError
的行为与 StandardError
是否包含无关,因为所有 StandardError
都被 rescue Exception
救援)。
示例
# bad
begin
something
rescue Exception
handle_exception
rescue StandardError
handle_standard_error
end
# bad
begin
something
rescue Exception, StandardError
handle_error
end
# good
begin
something
rescue StandardError
handle_standard_error
rescue Exception
handle_exception
end
# good, however depending on runtime environment.
#
# This is a special case for system call errors.
# System dependent error code depends on runtime environment.
# For example, whether `Errno::EAGAIN` and `Errno::EWOULDBLOCK` are
# the same error code or different error code depends on environment.
# This good case is for `Errno::EAGAIN` and `Errno::EWOULDBLOCK` with
# the same error code.
begin
something
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
handle_standard_error
end
Lint/ShadowingOuterLocalVariable
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.9 |
- |
检查在块参数或块局部变量中使用来自外部作用域的局部变量名。这反映了 Ruby 2.6 之前 ruby -cw
给出的警告:"shadowing outer local variable - foo"。
允许在传递给 Ractor.new 的块中遮蔽变量,因为 Ractor 不应该访问外部变量。例如,鼓励以下风格
|
worker_id, pipe = env
Ractor.new(worker_id, pipe) do |worker_id, pipe|
end
Lint/StructNewOverride
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.81 |
- |
检查通过 Struct.new
对 Struct
内置方法的意外覆盖。
示例
# bad
Bad = Struct.new(:members, :clone, :count)
b = Bad.new([], true, 1)
b.members #=> [] (overriding `Struct#members`)
b.clone #=> true (overriding `Object#clone`)
b.count #=> 1 (overriding `Enumerable#count`)
# good
Good = Struct.new(:id, :name)
g = Good.new(1, "foo")
g.members #=> [:id, :name]
g.clone #=> #<struct Good id=1, name="foo">
g.count #=> 2
Lint/SuppressedException
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.9 |
1.12 |
检查没有主体内容的 rescue
块。
示例
# bad
def some_method
do_something
rescue
end
# bad
begin
do_something
rescue
end
# good
def some_method
do_something
rescue
handle_exception
end
# good
begin
do_something
rescue
handle_exception
end
AllowComments: true(默认)
# good
def some_method
do_something
rescue
# do nothing
end
# good
begin
do_something
rescue
# do nothing
end
AllowComments: false
# bad
def some_method
do_something
rescue
# do nothing
end
# bad
begin
do_something
rescue
# do nothing
end
Lint/SymbolConversion
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终 |
1.9 |
1.16 |
检查将字面字符串转换为符号的使用情况,在这种情况下可以使用字面符号。
此 cop 有两种可能的风格。strict
(默认)将对任何不正确的用法注册违规。consistent
另外要求哈希对每个符号键使用相同的风格(即,如果任何符号键需要被引用,则要求所有键都被引用)。
示例
# bad
'string'.to_sym
:symbol.to_sym
'underscored_string'.to_sym
:'underscored_symbol'
'hyphenated-string'.to_sym
"string_#{interpolation}".to_sym
# good
:string
:symbol
:underscored_string
:underscored_symbol
:'hyphenated-string'
:"string_#{interpolation}"
Lint/ToEnumArguments
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.1 |
- |
确保为当前方法调用的 to_enum
/enum_for
具有正确的参数。
示例
# bad
def foo(x, y = 1)
return to_enum(__callee__, x) # `y` is missing
end
# good
def foo(x, y = 1)
# Alternatives to `__callee__` are `__method__` and `:foo`.
return to_enum(__callee__, x, y)
end
# good
def foo(x, y = 1)
# It is also allowed if it is wrapped in some method like Sorbet.
return to_enum(T.must(__callee__), x, y)
end
Lint/ToJSON
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
始终 |
0.66 |
- |
检查以确保 #to_json
包含可选参数。当覆盖 #to_json
时,调用者可以通过 JSON.generate(your_obj)
调用 JSON 生成。由于 JSON#generate
允许可选参数,因此您的方法也应该允许。
Lint/TripleQuotes
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
始终 |
1.9 |
- |
检查“三引号”(由任何大于 1 的奇数个引号分隔的字符串)。
Ruby 允许通过在语句中相邻来隐式连接多个字符串(例如 "foo""bar" == "foobar"
)。这有时会让人觉得三引号有什么特别之处,但实际上它只是额外的、不必要的引号,并且会生成相同的字符串。每对引号都会生成一个额外的连接的空字符串,因此结果仍然只是分隔符内的“实际”字符串。
虽然这个 cop 被称为三引号,但对于由 5、7 等引号分隔的字符串,也会出现相同的行为。 |
Lint/UnderscorePrefixedVariableName
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.21 |
- |
检查实际使用的下划线前缀变量。
由于块关键字参数不能在调用站点随意命名,因此 AllowKeywordBlockArguments
将允许使用下划线前缀的块关键字参数。
Lint/UnexpectedBlockArity
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
否 |
否 |
1.5 |
- |
检查已知需要比给定的位置块参数更多的块(默认情况下,这配置为 Enumerable
方法需要 2 个参数)。允许可选参数,尽管它们通常没有意义,因为将使用默认值。没有接收者或采用 splatted 参数(例如 *args
)的块始终被接受。
关键字参数(包括 **kwargs
)不会计入此数,因为它们不被相关方法使用。
可以像这样配置方法名称及其预期元数
Methods:
inject: 2
reduce: 2
Lint/UnmodifiedReduceAccumulator
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.1 |
1.5 |
查找 reduce
或 inject
块,其中返回的值(隐式或显式)不包含累加器。只要至少一个返回值包含累加器,块就被认为是有效的。
如果返回值中不包含累加器,则整个块将只返回最后一个元素值的转换,并且可以重写为不使用循环的形式。
还会捕获返回累加器索引的实例,因为这可能会改变被保留的对象类型。
为了减少误报,此 cop 仅标记 reduce 块中返回元素是表达式中唯一变量的返回值(因为我们无法通过静态分析确定其他变量之间的关系)。
|
示例
# bad
(1..4).reduce(0) do |acc, el|
el * 2
end
# bad, may raise a NoMethodError after the first iteration
%w(a b c).reduce({}) do |acc, letter|
acc[letter] = true
end
# good
(1..4).reduce(0) do |acc, el|
acc + el * 2
end
# good, element is returned but modified using the accumulator
values.reduce do |acc, el|
el << acc
el
end
# good, returns the accumulator instead of the index
%w(a b c).reduce({}) do |acc, letter|
acc[letter] = true
acc
end
# good, at least one branch returns the accumulator
values.reduce(nil) do |result, value|
break result if something?
value
end
# good, recursive
keys.reduce(self) { |result, key| result[key] }
# ignored as the return value cannot be determined
enum.reduce do |acc, el|
x = foo(acc, el)
bar(x)
end
Lint/UnreachableLoop
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.89 |
1.7 |
检查最多执行一次迭代的循环。
永远无法到达第二次迭代的循环可能是代码中的错误。在极少数情况下,如果只打算执行一次迭代(或最多执行一次迭代),则应将代码重构为使用 if
条件语句。
与 Enumerable 一起使用的块方法被认为是循环。
|
AllowedPatterns
可用于匹配代码块接收器,以允许原本会被注册为违规的代码(例如,times
不在 Enumerable
上下文中使用)。
示例
# bad
while node
do_something(node)
node = node.parent
break
end
# good
while node
do_something(node)
node = node.parent
end
# bad
def verify_list(head)
item = head
begin
if verify(item)
return true
else
return false
end
end while(item)
end
# good
def verify_list(head)
item = head
begin
if verify(item)
item = item.next
else
return false
end
end while(item)
true
end
# bad
def find_something(items)
items.each do |item|
if something?(item)
return item
else
raise NotFoundError
end
end
end
# good
def find_something(items)
items.each do |item|
if something?(item)
return item
end
end
raise NotFoundError
end
# bad
2.times { raise ArgumentError }
Lint/UnusedBlockArgument
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
仅限命令行 |
0.21 |
1.61 |
检查未使用的代码块参数。
Lint/UnusedMethodArgument
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
仅限命令行 |
0.21 |
1.61 |
检查未使用的函数参数。
示例
# bad
def some_method(used, unused, _unused_but_allowed)
puts used
end
# good
def some_method(used, _unused, _unused_but_allowed)
puts used
end
Lint/UriEscapeUnescape
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
否 |
0.50 |
- |
识别可以使用 CGI.escape
、URI.encode_www_form
或 URI.encode_www_form_component
替换 URI.escape
的地方,具体取决于您的特定用例。此外,此代码检查器还会识别可以使用 CGI.unescape
、URI.decode_www_form
或 URI.decode_www_form_component
替换 URI.unescape
的地方,具体取决于您的特定用例。
示例
# bad
URI.escape('http://example.com')
URI.encode('http://example.com')
# good
CGI.escape('http://example.com')
URI.encode_www_form([['example', 'param'], ['lang', 'en']])
URI.encode_www_form(page: 10, locale: 'en')
URI.encode_www_form_component('http://example.com')
# bad
URI.unescape(enc_uri)
URI.decode(enc_uri)
# good
CGI.unescape(enc_uri)
URI.decode_www_form(enc_uri)
URI.decode_www_form_component(enc_uri)
Lint/UselessAccessModifier
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
仅限命令行 |
0.20 |
1.61 |
检查冗余的访问修饰符,包括没有代码的修饰符、重复的修饰符以及类或模块主体中的前导 public
修饰符。条件定义的函数被认为始终被定义,因此保护此类函数的访问修饰符不是冗余的。
此代码检查器具有 ContextCreatingMethods
选项。默认设置值为一个空数组,这意味着没有指定函数。此设置是一个函数数组,当调用这些函数时,已知它们会在模块的当前访问上下文中创建自己的上下文。
它还具有MethodCreatingMethods
选项。默认设置值为空数组,表示未指定任何方法。此设置是一个方法数组,当调用这些方法时,已知它们会在模块的当前访问上下文中创建其他方法。
示例
# bad
class Foo
public # this is redundant (default access is public)
def method
end
end
# bad
class Foo
# The following is redundant (methods defined on the class'
# singleton class are not affected by the private modifier)
private
def self.method3
end
end
# bad
class Foo
protected
define_method(:method2) do
end
protected # this is redundant (repeated from previous modifier)
[1,2,3].each do |i|
define_method("foo#{i}") do
end
end
end
# bad
class Foo
private # this is redundant (no following methods are defined)
end
# good
class Foo
private # this is not redundant (a method is defined)
def method2
end
end
# good
class Foo
# The following is not redundant (conditionally defined methods are
# considered as always defining a method)
private
if condition?
def method
end
end
end
# good
class Foo
protected # this is not redundant (a method is defined)
define_method(:method2) do
end
end
ContextCreatingMethods:关注
# Lint/UselessAccessModifier:
# ContextCreatingMethods:
# - concerning
# good
require 'active_support/concern'
class Foo
concerning :Bar do
def some_public_method
end
private
def some_private_method
end
end
# this is not redundant because `concerning` created its own context
private
def some_other_private_method
end
end
Lint/UselessAssignment
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
仅命令行(不安全) |
0.11 |
1.61 |
检查每个作用域中对局部变量的每个无用赋值。此 cop 的基本思想来自ruby -cw
的警告。
assigned but unused variable - foo
目前,此 cop 具有高级逻辑,可以检测未引用的重新赋值,并正确处理分支、循环、救援、确保等各种情况。
给定赋值foo = 1, bar = 2 ,删除未使用的变量会导致语法错误,因此这种情况不会自动更正。
|
安全
此 cop 的自动更正不安全,因为从运算符赋值中删除赋值会导致 NameError,如果此赋值已用于声明局部变量。例如,将a ||= 1
替换为a || 1
可能会导致“未定义的局部变量或方法`a' for main:Object (NameError)”。
Lint/UselessMethodDefinition
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
仅命令行(不安全) |
0.90 |
1.61 |
检查无用的方法定义,具体来说:空构造函数和仅委托给super
的方法。
Lint/UselessRescue
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.43 |
- |
检查无用的 `rescue`,它只重新抛出被捕获的异常。
示例
# bad
def foo
do_something
rescue
raise
end
# bad
def foo
do_something
rescue => e
raise # or 'raise e', or 'raise $!', or 'raise $ERROR_INFO'
end
# good
def foo
do_something
rescue
do_cleanup
raise
end
# bad (latest rescue)
def foo
do_something
rescue ArgumentError
# noop
rescue
raise
end
# good (not the latest rescue)
def foo
do_something
rescue ArgumentError
raise
rescue
# noop
end
Lint/UselessRuby2Keywords
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
待定 |
是 |
否 |
1.23 |
- |
查找对不需要它的方法的 ruby2_keywords
调用。
ruby2_keywords
应该只在接受参数 splat (*args
) 但不接受显式关键字参数 (k:
或 k: true
) 或关键字 splat (**kwargs
) 的方法上调用。
示例
# good (splat argument without keyword arguments)
ruby2_keywords def foo(*args); end
# bad (no arguments)
ruby2_keywords def foo; end
# good
def foo; end
# bad (positional argument)
ruby2_keywords def foo(arg); end
# good
def foo(arg); end
# bad (double splatted argument)
ruby2_keywords def foo(**args); end
# good
def foo(**args); end
# bad (keyword arguments)
ruby2_keywords def foo(i:, j:); end
# good
def foo(i:, j:); end
# bad (splat argument with keyword arguments)
ruby2_keywords def foo(*args, i:, j:); end
# good
def foo(*args, i:, j:); end
# bad (splat argument with double splat)
ruby2_keywords def foo(*args, **kwargs); end
# good
def foo(*args, **kwargs); end
# bad (ruby2_keywords given a symbol)
def foo; end
ruby2_keywords :foo
# good
def foo; end
# bad (ruby2_keywords with dynamic method)
define_method(:foo) { |arg| }
ruby2_keywords :foo
# good
define_method(:foo) { |arg| }
Lint/UselessTimes
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
否 |
仅命令行(不安全) |
0.91 |
1.61 |
检查 Integer#times
的使用,这些使用永远不会产生 (当整数 ⇐ 0
) 或只产生一次 (1.times
)。
Lint/Void
默认启用 | 安全 | 支持自动更正 | 添加版本 | 更改版本 |
---|---|---|---|---|
启用 |
是 |
仅限命令行 |
0.9 |
1.61 |
检查在 void 上下文中使用的运算符、变量、字面量、lambda、proc 和非变异方法。
each
块被允许以防止误报。例如,下面 each
块中的表达式。它不是 void,尤其是在接收者是 Enumerator
时
enumerator = [1, 2, 3].filter
enumerator.each { |item| item >= 2 } #=> [2, 3]