※ この記事はHaskellで複雑度測定からの転載です。
自分で書いているブログのPVが増えなくて悲しいので、こういうところにも載せて見たら多少増えるんじゃないかと思って試しに載せて見ます。
Haskellでサイクロマティック複雑度(循環的複雑度)を測定する場合、2つツールがあるようです。
githubのスター数はargonの方が多いのですが、コミット履歴を見るとhomplexityの方が今もメンテナンスされているようなのでhomplexityがオススメです。機能的な違いは特に調べていません。
公式サイトによれば、以下の統計値を出してくれるようです。
本題から外れますがBranching depthってなんでしょうか。説明には
Branching is used with conditionals and has been used as a criterion for both software complexity and logic.
と書いてあります。分岐の数のことなんでしょうか。ちょっと試して見たところ、if分岐がある場合でも0でしたが、ifの中にifをネストさせると1になり、ifの中にifの中にifとネストさせると2になりました。だから分岐の深さってことか。なんかサイクロマティック複雑度と似ていますね。
stackが入っていれば簡単です。クローンしてstack installするだけです。
git clone https://github.com/mgajda/homplexity.git
cd homplexity
stack install
で、~/.local/bin
にhomplexity-cli
ができるはずです。パスを通すなら、~/.bashrc
や~/.bash_profile
などに
PATH=$PATH:~/.local/bin
を追記すれば良いです。
これで簡単にインストールできるのは良いのですが、このリポジトリで指定しているGHCバージョンが入っていない場合、そのインストールと依存パッケージのインストールから始めるので結構時間がかかるかもしれません。これがstackのデメリットですよね(メリットなのか?cabal hellという言葉を思い出した、そしてWhat is Cabal Hell?というStackoverflowを見つけたw)。
githubリポにも書いてありますが、以下のようにメインモジュールファイルと依存モジュールのルートディレクトリを指定します。
# プロジェクトディレクトリ構成がこのようになっている場合
root --- app --- Main.hs
|
|- src --- Lib.hs
|- ...
homplexity-cli app/Main.hs src/
これで、メインモジュールと依存モジュールファイル群を見つけて各メソッドの複雑度を測定してくれます。出力は、
Warning:src/InterfaceAdapter/Presenter/StockAPIHandler.hs:SrcLoc "src/InterfaceAdapter/Presenter/StockAPIHandler.hs" 34 1:function stockServer has 48 lines of code should be kept below 20 lines of code.
Correctly parsed 16 out of 16 input files.
こんなのが出てきます。このファイルのこのメソッドが48行もあるから20行未満に抑えた方が良いよ、と言っています。これは複雑度ではありませんが。
もっと詳細な情報を出して欲しい場合は--severity
というオプションを使います。ログレベルの設定のような感じです。homplexity -h
を見てもらえばわかりますが、
# ヘルプの説明
--severity={Debug|Info|Warning|Critical} level of output verbosity (Debug Info Warning Critical) (default: Warning, from module: Main)
とのことなのでデフォルトはWarningですがInfoにすればもっと色々出てきます。以下はInfoで解析した時の出力の一部です。
homplexity-cli --severity=Info app/Main.hs src/
Info:app/Main.hs:SrcLoc "app/Main.hs" 1 1:module Main has 14 lines of code
Info:app/Main.hs:SrcLoc "app/Main.hs" 8 1:type signature for main has type constructor nesting of 1
Info:app/Main.hs:SrcLoc "app/Main.hs" 8 1:type signature for main has 1 arguments
Info:app/Main.hs:SrcLoc "app/Main.hs" 9 1:function main has 8 lines of code
Info:app/Main.hs:SrcLoc "app/Main.hs" 9 1:function main has cyclomatic complexity of 1
Info:app/Main.hs:SrcLoc "app/Main.hs" 9 1:function main has branching depth of 0
これは、Makefileなどに書いておいて、毎回ビルドの時に一緒に測定してもらうなどが良さそうですね。それかIDEでファイル保存のトリガーで実行してくれる方が良いのかな。そこで警告などが出てくれればソースコードを見直そうという気になるかもしれません。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント