Условие ветви задания для install_package слишком высокое - PullRequest
0 голосов
/ 27 марта 2020

Я впервые использую Ruby, и я запускаю Rubocop для проверки своего кода и получения предупреждения Assignment Branch Condition for install_package is too high. Я взглянул на некоторые вопросы, касающиеся этой проблемы, но я немного не уверен, как решить эту проблему в моей ситуации. Буду признателен за любой совет:

def install_package
    node.run_state['fullList'].each do |p|
        rpm_package p do
            source "#{node.run_state['repo]}/#{p}"
            options "--prefix #{node['sw']['swclient']['install_path']}/#{node.run_state['sw_inst_path']}"
            action :install
            only_if { node.run_state['failureCount'].zero? }
        end
    end
end

1 Ответ

2 голосов
/ 27 марта 2020

Прежде всего вам нужно знать, что такое условие ветви назначения, прежде чем мы сможем решить эту проблему:

При просмотре файла default config мы видим, что максимальное значение по умолчанию равно 15, и это ссылки на http://c2.com/cgi/wiki?AbcMetric и https://en.wikipedia.org/wiki/ABC_Software_Metric.

Давайте сначала посмотрим на ссылки. Первая ссылка гласит следующее:

  • Назначение - явный перенос данных в переменную, например, = * = / =% = + = << = >> = & = | = ^ = >>> = ++ -
  • Ветвь - явная прямая ветвь программы вне области видимости - вызов функции, вызов метода класса или новый оператор
  • Условие - логический / логический тест, ==! = <=> = <> в противном случае по умолчанию try catch? и унарные условные выражения.

Скалярное значение размера AB C (или «совокупная величина») вычисляется как:

|ABC| = sqrt((A*A)+(B*B)+(C*C))

Суммировано: Количество назначений увеличивается, когда Вы назначаете что-то переменной. Количество ветвей увеличивается, когда вы вызываете метод или функцию. Количество условий увеличивается при выполнении сравнений, таких как 1 > 2.

. Применяя это к вашему коду, мы видим, что это приводит к следующему числу:

def install_package
  node.run_state['fullList'].each do |p|
  # ^B ^B       ^B           ^B

    rpm_package p do
    # ^B
      source "#{node.run_state['repo']}/#{p}"
      # ^B      ^B   ^B       ^B
      options "--prefix #{node['sw']['swclient']['install_path']}/#{node.run_state['sw_inst_path']}"
      # ^B                ^B  ^B    ^B          ^B                  ^B   ^B       ^B
      action :install
      # ^B
      only_if { node.run_state['failureCount'].zero? }
      # ^B      ^B   ^B       ^B               ^B
    end
  end
end

В результате получается размер AB C из:

Math.sqrt(0**2 + 23**2 + 0**2) #=> 23

Позвольте мне начать с того, что стандартный максимальный размер AB C довольно низок. И вы можете захотеть сделать это в вашем RuboCop config или отключить настройку все вместе. Теперь давайте посмотрим, как решить эту проблему.

Большую часть времени, когда размер AB C является проблемой, это означает, что у вас слишком большая сложность в вашем методе. Самый простой способ решить эту проблему - создать вспомогательные методы и извлечь сложность из основного метода.

Другой вариант - присвоить значения метода, возвращаемые переменной. таким образом вы кешируете возвращаемое значение. Например, вы вызываете метод node 5 раз. Вы можете сохранить результат метода в переменной и использовать его вместо этого. node = self.node Таким образом, вы заменяете 5 ветвей на 1 ветвь и 1 присваивание.

Я разработал пример решения, которое извлекает сложность из метода install_package, в этом ответе предполагается, что код помещен в класс или контекст модуля (в противном случае private не имеет смысла).

def install_packages # ABC-size Math.sqrt(0**2 + 12**2 + 1**2) #=> 12.041...
  node.run_state['fullList'].each do |package|
  # ^B ^B       ^B           ^B
    rpm_package package do
    # ^B
      source package_source(package)
      # ^B   ^B
      options "--prefix #{install_path}"
      # ^B                ^B
      action :install
      # ^B
      only_if { !failures? }
      # ^B      ^C ^B
    end
  end
end

private

def package_source(package) # ABC-size Math.sqrt(0**2 + 3**2 + 0**2) #=> 3
  "#{node.run_state['repo']}/#{package}"
  #  ^B   ^B       ^B
end

def install_path # ABC-size Math.sqrt(2**2 + 7**2 + 0**2) #=> 7.280...
  root_install_path = node['sw']['swclient']['install_path']
  #                 ^A ^B ^B    ^B          ^B
  relative_install_path = node.run_state['sw_inst_path']
  #                     ^A ^B  ^B       ^B
  "#{root_install_path}/#{relative_install_path}"
end

def failures? # ABC-size Math.sqrt(0**2 + 4**2 + 0**2) #=> 4
  node.run_state['failureCount'].positive?
  # ^B ^B       ^B               ^B
end

Примечание: Я не совсем уверен, что восклицательный знак в !value относится к ветвям или условия. Ради примеров я посчитал их условными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...