Как работает слишком большой размер условия ветки назначения для индекса?

Рубокоп всегда сообщает об ошибке:

app/controllers/account_controller.rb:5:3: C: Размер условия ветви назначения для индекса слишком велик. [30,95/24]

if params[:role]
  @users = @search.result.where(:role => params[:role])
elsif params[:q] && params[:q][:s].include?('count')
  @users = @search.result.order(params[:q][:s])
else
  @users = @search.result
end

Как это исправить? У кого-нибудь есть хорошая идея?


person pangpang    schedule 09.01.2016    source источник


Ответы (1)


Размер ABC [1][2]

вычисляется путем подсчета количества назначений, ветвей и условий для раздела кода. Правила подсчета в оригинальной статье C++ Report были специально для языков C, C++ и Java.

В предыдущих ссылках подробно описано, что считается для A, B и C. Размер ABC — это скалярная величина, напоминающая триангулированное отношение:

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

Собственно, беглый гугль по ошибке показывает, что первой проиндексированной страницей является документы Rubocop для метода, который отображает это сообщение.

Ваш инструмент репо или анализа определит пороговую сумму при срабатывании предупреждения.

Расчет, если вам нравится причинять себе вред...

Ваш код рассчитывается как

(1+1+1)^2  + 
(1+1+1+1+1+1+1+1+1+1+1+1+1)^2   + 
(1+1+1+1)^2 
=> 194 

Это «слепой» расчет со значениями, которые я составил (1s). Однако вы можете видеть, что в ошибке указаны числа, которые, вероятно, теперь имеют смысл как ваша ABC и порог:

 [30.95/24]

Таким образом, порог копа равен 24, а ваш ABC size равен 30.95. Это говорит нам о том, что механизм rubocop присваивает разные номера для A, B и C. Кроме того, разные виды или назначения (или B или C) также могут иметь разные значения. НАПРИМЕР. «нормальное» задание x = y, возможно, оценивается ниже, чем связанное задание x = y = z = r.

тл;д-р ответ

На данный момент у вас, вероятно, есть довольно четкое представление о том, как уменьшить размер ABC. Если не:

  1. простой способ взять условное выражение, используемое для вашего elsif, и поместить его во вспомогательный метод.
  2. поскольку вы назначаете переменную @ и в основном вызываете из нее, ваш код не использует инкапсуляцию памяти. Таким образом, вы можете переместить как if, так и elsif действия блока в свои собственные методы load_search_users_by_role и load_search_users_by_order.
person New Alexandria    schedule 09.01.2016
comment
Спасибо за объяснение - person pangpang; 09.01.2016
comment
@pangpang Вы должны использовать «взрыв» (!) в конце имени метода, как я уже писал, поскольку это соглашение ruby, когда метод изменяет данные / состояние в результате выполнения. Также спасибо и рад - person New Alexandria; 09.01.2016
comment
Нет, это не соглашение. Соглашение состоит в том, что если и только если есть два метода, которые делают одно и то же, то тот, который более удивителен, называется с треском. Это не имеет ничего общего с мутацией (см., например, save против save! в ActiveRecord или exit против exit! в Ruby) и применяется только при наличии двух< /i> методы (см., например, около дюжины методов в Array, String или Hash, которые модифицируют приемник, но не имеют взрыва.) Метод взрыва должен быть только в том случае, если есть также метод без взрыва с то же имя. - person Jörg W Mittag; 09.01.2016
comment
@jorgwmittag Я вижу, ты публикуешь много хороших вещей. Я поймаю тебя на слове. - person New Alexandria; 09.01.2016
comment
Ссылка c2.com не работает — вот еще одно хорошее описание: hub .codebeat.co/docs/ - person RubyTuesdayDONO; 13.10.2016