Rails

サイクロマティック複雑度を学ぶ

07/10/2023



サイクロマティック複雑度について、教わった内容をふりかえります。


まず、昨日遭遇したrubocopの警告は以下です。

app/forms/bill_group_form.rb:119:5: C: Metrics/PerceivedComplexity: Perceived complexity for xxxxxxxxxxxxxxxxxxxxxxx is too high. [9/8]

    def xxxxxxxxxxxxxxxxxxxxxxx

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^




訳し方に戸惑いましたが、個人的には「認められた複雑性」がしっくりきました。


Metrics : 測定法

PerceivedComplexity: 感知された複雑性


今回の警告は変更した箇所に付いてではなく、指摘されたメソッド内全体を見ていく必要があります。


変更箇所が加えられた結果、メソッド内の複雑性が増していることを指摘されています。


変更箇所自体がシンプルであれば、その他の箇所も含めて改善できる点がないか検討したほうが良いです。


lintは以下リンク先にきさいのとおり、「PerceivedComplexity」クラスで走っています。


サイクロマティック複雑度(CyclomaticComplexity)を拡張しwhenの計測に対応させたバージョンであることを教わりました。


参照リンク | rubocop/lib/rubocop/cop/metrics /perceived_complexity.rb



おおよそですが、コメント内のポイントを書き出してみます。

  • Metricsは読み手がメソッド内容を複雑に感じないかをスコアとして測定する方法を提供しています。
  • その観点から、when は if や&& ほど複雑ではないものとしています。
  • copはすべてのwhen節を if / elsif / elsif ... としてあつかいます。
  • サイクロマティック複雑性copと対象的に、このcopはelseについては複雑性を増すものとしています。


@ example をみるとスコア計測についてイメージしやすかったです。



サイクロマティック複雑性については以下のURLがとても参考になりました。


参照リンク | サイクロマティック複雑度の活用


【Note】

サイクロマティック複雑度を求める公式 : エッジの数 - ノードの数 + 2 

この場合は、node → 中継点・分岐点、edge → 接線 と考えると覚えやすい。

サイクロマティック複雑度が51以上だとテストが不可能な状態でバグの混入確率も大きく上がる(レポート作成元によって数値は異なる。)

一般的なチームは10を超えないことを目安にする。

サイクロマティック複雑性が高い→テストすべき実行パスが多い。それゆえ運用・保守・開発の負担が増加する。

-Rails
-, ,