指标

指标/AbcSize

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

启用

0.27

1.5

检查方法的 ABC 大小是否不高于配置的最大值。ABC 大小基于赋值、分支(方法调用)和条件。参见 http://c2.com/cgi/wiki?AbcMetrichttps://en.wikipedia.org/wiki/ABC_Software_Metric.

解释 ABC 大小

  • ⇐ 17 令人满意

  • 18..30 不令人满意

  • > 30 危险

您可以将重复的“属性”调用计为单个“分支”。为此目的,属性是指任何没有参数的方法;没有试图区分实际的 attr_reader 与其他方法。

此 cop 还考虑 AllowedMethods(默认值为 [])和 AllowedPatterns(默认值为 []

示例

CountRepeatedAttributes: false(默认值为 true)

# `model` and `current_user`, referenced 3 times each,
# are each counted as only 1 branch each if
# `CountRepeatedAttributes` is set to 'false'

def search
  @posts = model.active.visible_by(current_user)
            .search(params[:q])
  @posts = model.some_process(@posts, current_user)
  @posts = model.another_process(@posts, current_user)

  render 'pages/search/page'
end

可配置属性

名称 默认值 可配置值

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

CountRepeatedAttributes

true

布尔值

Max

17

整数

Metrics/BlockLength

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

启用

0.44

1.5

检查代码块的长度是否超过最大值。可选地可以忽略注释行。允许的最大长度是可配置的。该规则可以配置为忽略传递给某些方法的代码块。

您可以使用 `CountAsOne` 设置要折叠的结构。可用的选项包括:'array'、'hash'、'heredoc' 和 'method_call'。无论实际大小如何,每个结构都将被计为一行。

此规则不适用于 `Struct` 定义。
`ExcludedMethods` 配置已弃用,仅保留用于向后兼容。请改用 `AllowedMethods` 和 `AllowedPatterns`。默认情况下,没有允许的方法。

示例

CountAsOne: ['array', 'heredoc', 'method_call']

something do
  array = [         # +1
    1,
    2
  ]

  hash = {          # +3
    key: 'value'
  }

  msg = <<~HEREDOC  # +1
    Heredoc
    content.
  HEREDOC

  foo(              # +1
    1,
    2
  )
end                 # 6 points

可配置属性

名称 默认值 可配置值

CountComments

false

布尔值

Max

25

整数

CountAsOne

[]

数组

AllowedMethods

refine

数组

AllowedPatterns

[]

数组

Exclude

**/*.gemspec

数组

Metrics/BlockNesting

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

启用

0.25

0.47

检查条件和循环结构的嵌套是否过多。

您可以使用 `CountBlocks` 选项配置是否考虑代码块。当设置为 `false`(默认值)时,代码块不会计入嵌套级别。设置为 `true` 以将代码块也计入。

允许的最大嵌套级别是可配置的。

可配置属性

名称 默认值 可配置值

CountBlocks

false

布尔值

Max

3

整数

Metrics/ClassLength

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

启用

0.25

0.87

检查类的长度是否超过最大值。可选地可以忽略注释行。允许的最大长度是可配置的。

您可以使用 `CountAsOne` 设置要折叠的结构。可用的选项包括:'array'、'hash'、'heredoc' 和 'method_call'。无论实际大小如何,每个结构都将被计为一行。

此规则也适用于 `Struct` 定义。

示例

CountAsOne: ['array', 'heredoc', 'method_call']

class Foo
  ARRAY = [         # +1
    1,
    2
  ]

  HASH = {          # +3
    key: 'value'
  }

  MSG = <<~HEREDOC  # +1
    Heredoc
    content.
  HEREDOC

  foo(              # +1
    1,
    2
  )
end                 # 6 points

可配置属性

名称 默认值 可配置值

CountComments

false

布尔值

Max

100

整数

CountAsOne

[]

数组

Metrics/CollectionLiteralLength

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

待定

1.47

-

检查具有大量条目的字面量。这表明配置或数据可能最好提取到其他地方,例如数据库、从 API 获取或从非代码文件(CSV、JSON、YAML 等)读取。

示例

# bad
# Huge Array literal
[1, 2, '...', 999_999_999]

# bad
# Huge Hash literal
{ 1 => 1, 2 => 2, '...' => '...', 999_999_999 => 999_999_999}

# bad
# Huge Set "literal"
Set[1, 2, '...', 999_999_999]

# good
# Reasonably sized Array literal
[1, 2, '...', 10]

# good
# Reading huge Array from external data source
# File.readlines('numbers.txt', chomp: true).map!(&:to_i)

# good
# Reasonably sized Hash literal
{ 1 => 1, 2 => 2, '...' => '...', 10 => 10}

# good
# Reading huge Hash from external data source
CSV.foreach('numbers.csv', headers: true).each_with_object({}) do |row, hash|
  hash[row["key"].to_i] = row["value"].to_i
end

# good
# Reasonably sized Set "literal"
Set[1, 2, '...', 10]

# good
# Reading huge Set from external data source
SomeFramework.config_for(:something)[:numbers].to_set

可配置属性

名称 默认值 可配置值

LengthThreshold

250

整数

Metrics/CyclomaticComplexity

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

启用

0.25

0.81

检查方法的圈复杂度是否超过配置的最大值。圈复杂度是指方法中线性无关路径的数量。该算法计算决策点并加一。

if 语句(或 unless 或 ?:) 会将复杂度增加一。else 分支不会增加复杂度,因为它不会添加决策点。&& 运算符(或关键字 and)可以转换为嵌套的 if 语句,而 ||/or 是 if 序列的简写,因此它们也会增加一。循环可以被认为具有退出条件,因此它们也会增加一。调用内置迭代方法(例如 `ary.map{…​}`)的代码块也会增加一,其他代码块会被忽略。

def each_child_node(*types)               # count begins: 1
  unless block_given?                     # unless: +1
    return to_enum(__method__, *types)
children.each do |child|                # each{}: +1
  next unless child.is_a?(Node)         # unless: +1
  yield child if types.empty? ||        # if: +1, ||: +1
                 types.include?(child.type)
end
  self
end                                       # total: 6

可配置属性

名称 默认值 可配置值

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

Max

7

整数

Metrics/MethodLength

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

启用

0.25

1.5

检查方法的长度是否超过某个最大值。可以选择允许注释行。允许的最大长度是可配置的。

您可以使用 `CountAsOne` 设置要折叠的结构。可用的选项包括:'array'、'hash'、'heredoc' 和 'method_call'。无论实际大小如何,每个结构都将被计为一行。

ExcludedMethodsIgnoredMethods 配置已弃用,仅保留用于向后兼容。请改用 AllowedMethodsAllowedPatterns。默认情况下,没有允许的方法。

示例

CountAsOne: ['array', 'heredoc', 'method_call']

def m
  array = [       # +1
    1,
    2
  ]

  hash = {        # +3
    key: 'value'
  }

  <<~HEREDOC      # +1
    Heredoc
    content.
  HEREDOC

  foo(            # +1
    1,
    2
  )
end               # 6 points

可配置属性

名称 默认值 可配置值

CountComments

false

布尔值

Max

10

整数

CountAsOne

[]

数组

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

Metrics/ModuleLength

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

启用

0.31

0.87

检查模块的长度是否超过某个最大值。可以选择忽略注释行。允许的最大长度是可配置的。

您可以使用 `CountAsOne` 设置要折叠的结构。可用的选项包括:'array'、'hash'、'heredoc' 和 'method_call'。无论实际大小如何,每个结构都将被计为一行。

示例

CountAsOne: ['array', 'heredoc', 'method_call']

module M
  ARRAY = [         # +1
    1,
    2
  ]

  HASH = {          # +3
    key: 'value'
  }

  MSG = <<~HEREDOC  # +1
    Heredoc
    content.
  HEREDOC

  foo(              # +1
    1,
    2
  )
end                 # 6 points

可配置属性

名称 默认值 可配置值

CountComments

false

布尔值

Max

100

整数

CountAsOne

[]

数组

Metrics/ParameterLists

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

启用

0.25

1.5

检查参数过多的方法。

参数的最大数量是可配置的。可以选择从总计中排除关键字参数,因为它们比位置参数或可选参数添加的复杂度更低。

Struct.newData.define 的代码块中,initialize 方法的任何数量的参数始终是允许的

Struct.new(:one, :two, :three, :four, :five, keyword_init: true) do
  def initialize(one:, two:, three:, four:, five:)
  end
end

这是因为检查 initialize 方法的参数数量没有意义。

显式代码块参数 &block 不计入,以防止通过使代码块参数隐式来避免错误的更改。

此 cop 还检查可选参数的最大数量。这可以使用 MaxOptionalParameters 配置选项进行配置。

示例

Max: 3

# good
def foo(a, b, c = 1)
end

Max: 2

# bad
def foo(a, b, c = 1)
end

CountKeywordArgs: true (默认)

# counts keyword args towards the maximum

# bad (assuming Max is 3)
def foo(a, b, c, d: 1)
end

# good (assuming Max is 3)
def foo(a, b, c: 1)
end

CountKeywordArgs: false

# don't count keyword args towards the maximum

# good (assuming Max is 3)
def foo(a, b, c, d: 1)
end

MaxOptionalParameters: 3 (默认)

# good
def foo(a = 1, b = 2, c = 3)
end

MaxOptionalParameters: 2

# bad
def foo(a = 1, b = 2, c = 3)
end

可配置属性

名称 默认值 可配置值

Max

5

整数

CountKeywordArgs

true

布尔值

MaxOptionalParameters

3

整数

Metrics/PerceivedComplexity

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

启用

0.25

0.81

尝试生成一个复杂度评分,该评分衡量读者在查看方法时所感受到的复杂程度。为此,它将when节点视为不增加与if&&一样多的复杂度的元素。除非它是那些特殊的case/when结构,其中case之后没有表达式。然后,该cop将其视为if/elsif/elsif…​并让所有when节点都进行计数。与CyclomaticComplexity cop不同,此cop认为else节点会增加复杂度。

示例

def my_method                   # 1
  if cond                       # 1
    case var                    # 2 (0.8 + 4 * 0.2, rounded)
    when 1 then func_one
    when 2 then func_two
    when 3 then func_three
    when 4..10 then func_other
    end
  else                          # 1
    do_something until a && b   # 2
  end                           # ===
end                             # 7 complexity points

可配置属性

名称 默认值 可配置值

AllowedMethods

[]

数组

AllowedPatterns

[]

数组

Max

8

整数