新卒エンジニアの@yhorikawaです
普段railsを使って開発をしており、rubocopを使う機会があるのですが、
ある日rubocopを実行すると以下のように表示されました
Metrics/AbcSize: Assignment Branch Condition size for auth is too high. [17.5/15]
毎日のように、このAbcSizeに怒られいったいAbcってなんだろうと思ったのがこの記事を書くきっかけです。
rubocopの指摘するabc sizeとは
abc sizeとは次のように定義されます
Assignment -- an explicit transfer of data into a variable, e.g. = = /= %= += <<= >>= &= |= ^= >>>= ++ --
Branch -- an explicit forward program branch out of scope -- a function call, class method call, or new operator
Condition -- a logical/Boolean test, == != <= >= < > else case default try catch ? and unary conditionals.
A scalar ABC size value (or "aggregate magnitude") is computed as:
|ABC| = sqrt((AA)+(BB)+(CC))
http://wiki.c2.com/?AbcMetric より
Assignment: 変数への代入
Branch: 関数の呼び出し
Condition: 条件分岐
この三つをそれぞれ二条の平方根がAbcSizeとなります。
rubocopではこのAbcSizeがデフォルトで15を超えると警告を出すようになっています
この指摘をされたとき僕が書いていたコードはこのような内容でした
start_day = Date.new('2020,12,1')
end_day = Date.new('2020,12,10')
if @user.birthday > start_day && @user.birthday < end_day
1 + (end_day - start_day)
else
(end_day - start_day)
end
実際にはもっといろいろ書いていましたが、このように
変数への代入も多く、関数呼び出しも条件分岐もあるという形でAbc sizeが大きくなりrubocopに指摘を受けたようです。
どのように解決するのか
指摘を受けたからには修正したいですが、どのように解決するのでしょうか
1つのメソッドが複雑すぎるためこの指摘をされているので、
メソッドを適切に分割して1つのメソッドの複雑度を下げていくのが良いと思います。
力技でなんとかする
上の方法で解決しようと思ったけど、難しい場合rubocopのルールを変更することもできます。
rubocop.ymlに設定を追加しましょう
Metrics/AbcSize:
Max: 18
これでアラートも出なくなりました!
この方法は普通に解決できなかった時の最終手段です。
アラートを消すためにルールを変更して、rubocopを導入した本来の目的(指摘された箇所を訂正して品質を高めるなど)を見失わないように気をつけてください。
しかし、厳しすぎるルールを設定するのもあまり意味がないので、チームで相談して適切な値を探っていけると良いなと思います。
まとめ
今回はrubocopを使っているとよく怒られるabc sizeについてまとめてみました。
このルールもそうですが、rubocopに何故怒られているのか知っていけると、自分自身良いコードが書けるようになるのではと思いました。
Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2020 17日目の記事は、いかがでしたでしょうか。
明日は先輩エンジニアの @ysysysys です!! お楽しみに!
参考
http://hikitest.hatenablog.com/entry/2015/01/14/034346
https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators