今、話題の人工知能(AI)などで人気のPython。初心者に優しいとか言われていますが、全然優しくない! という事を、つらつら、愚痴っていきます

355.PMD(5)

»

初回:2024/03/13

 PMDのソースチェックに関しては、前回までで終了です。

P子「終わりなのに続いているの?」※1

 今回は、PMDで出来るもう一つの機能『Copy/Paste Detector』を使ってみたいと思います。

1.PMD の CPD(Copy/Paste Detector) とは

P子「聞くまでもないと思うけど、一応説明して」

 内容としては、コピー&ペーストされたコードを見つけるという機能です。ソースコードの作成において、同じようなコードが複数の箇所に分散している状態は、バグの温床になりうるという事です。

P子「温床という事は、まだバグにはなってないという事?」

 重複コードの問題点は、修正が必要になったときに修正漏れを引き起こしたり、Aコードを修正後テストしてOKでも、Bコードも同様に修正した所、類似コード(つまり同じではない)ため、Aと同じ修正では、Bはうまく動かないにも関わらず、テストを行わないとか緩いテストになっていたりするかもしれません。

P子「そんなの修正するコードはきちんと検証しなきゃダメでしょ」

 つまり、本来なら1か所だけ修正してAPIレベルで検証すれば済むところを、関連するソースコードをひとつ残らず見つけて修正して検証する必要があるので、その際にミスする確率が爆発的に増えます。それが、バグの温床と言われるゆえんです。

 そもそも、完全重複コードではなく微妙に改変されている訳で、本来修正が必要な個所の特定だけでも時間がかかりますし、発見できない事もあります。発見に時間がかかり修正ミスの可能性も高まり検証も時間がかかるので、良いことは何一つありません。

P子「なのに重複コードがこんなに多いのはなぜ?」

 簡単な事です。コピー&ペーストでプログラムを作るのが簡単だからです。

《参考資料1》
  https://enterprisezine.jp/article/detail/10412
  コードが美しくないために起きる問題を考える(前編)―重複のあるコード/誤読問題
  「EnterpriseZine」(エンタープライズジン)
  小野 和俊[著] / 有馬三郎[著]
  更新日: 2018/03/05

2.PMD の CPD の実行

 PMDの第一回で、ソースチェックのコマンドラインを書きましたが、同様に、CPD の実行コマンドラインを示します。

 Javaのパスを通したうえで、help を実行してみましょう

bin\pmd.bat cpd -h
Usage: pmd cpd [-Dh] [--ignore-annotations] [--ignore-identifiers]
               [--ignore-literal-sequences] [--ignore-literals]
               [--ignore-sequences] [--ignore-usings] [--[no-]
               fail-on-violation] [--no-skip-blocks] [--non-recursive]
               [--skip-duplicate-files] [--skip-lexical-errors] [-e=]
               [-f=] [--file-list=] [-l=]
               --minimum-tokens=
               [--skip-blocks-pattern=] [-u=]
               [-d=[,...]...]...
               [--exclude=...]... [-z=[,
               ...]...]... [...]
Copy/Paste Detector - find duplicate code
      [...]      Path to a source file, or directory containing
                               source files to analyze. Equivalent to using
                               --dir.
  -d, --dir=[,...]...
                             Path to a source file, or directory containing
                               source files to analyze. Zip and Jar files are
                               also supported, if they are specified directly
                               (archive files found while exploring a directory
                               are not recursively expanded). This option can
                               be repeated, and multiple arguments can be
                               provided to a single occurrence of the option.
                               One of --dir, --file-list or --uri must be
                               provided.
  -D, -v, --debug, --verbose Debug mode.
  -e, --encoding=  Specifies the character set encoding of the source
                               code files
                               Default: UTF-8
      --exclude=...
                             Files to be excluded from the analysis
                               Default: []
  -f, --format=
                             Report format.
                             Valid values: csv, csv_with_linecount_per_file,
                               text, vs, xml
                             Alternatively, you can provide the fully qualified
                               name of a custom CpdRenderer in the classpath.
                               Default: text
      --file-list=
                             Path to a file containing a list of files to
                               analyze, one path per line. One of --dir,
                               --file-list or --uri must be provided.
  -h, --help                 Show this help message and exit.
      --ignore-annotations   Ignore language annotations when comparing text.
      --ignore-identifiers   Ignore names of classes, methods, variables,
                               constants, etc. when comparing text.
      --ignore-literal-sequences
                             Ignore sequences of literals such as list
                               initializers.
      --ignore-literals      Ignore literal values such as numbers and strings
                               when comparing text.
      --ignore-sequences     Ignore sequences of identifiers and literals
      --ignore-usings        Ignore using directives in C#
  -l, --language=  The source code language.
                             Valid values: apex, coco, cpp, cs, dart,
                               ecmascript, fortran, gherkin, go, groovy, html,
                               java, jsp, julia, kotlin, lua, matlab, modelica,
                               objectivec, perl, php, plsql, pom, python, ruby,
                               scala, swift, tsql, typescript, vf, vm, wsdl,
                               xml, xsl
                               Default: java
      --minimum-tokens=
                             The minimum token length which should be reported
                               as a duplicate.
                               Default: 0
      --[no-]fail-on-violation
                             By default PMD exits with status 4 if violations
                               are found. Disable this option with
                               '--no-fail-on-violation' to exit with 0 instead
                               and just write the report.
      --no-skip-blocks       Do not skip code blocks marked with
                               --skip-blocks-pattern (e.g. #if 0 until #endif).
      --non-recursive        Don't scan subdirectiories.
      --skip-blocks-pattern=
                             Pattern to find the blocks to skip. Start and End
                               pattern separated by |.
                               Default: #if 0|#endif
      --skip-duplicate-files Ignore multiple copies of files of the same name
                               and length in comparison.
      --skip-lexical-errors  Skip files which can't be tokenized due to invalid
                               characters, instead of aborting with an error.
-u, --uri= Database URI for sources. One of --dir,
--file-list or --uri must be provided.
-z, --relativize-paths-with=[,
...]...
Path relative to which directories are rendered in
the report. This option allows shortening
directories in the report; without it, paths are
rendered as mentioned in the source directory
(option "--dir"). The option can be repeated, in
which case the shortest relative path will be
used. If the root path is mentioned (e.g. "/" or
"C:\"), then the paths will be rendered as
absolute.
P子「難しそうね」

 そうでもありません。必要なのは、実行するソースコードのフォルダと、検出条件となる 最小トークン数だけです。

 call 《独自にJavaの環境設定を行うbatファイル》
 set SRC_PATH=c:\src
 call bin\pmd.bat cpd --dir %SRC_PATH% --minimum-tokens=100 > pmd_cpd.txt

3.まとめ

 重複コードの検出は、多人数での開発や委託開発時のチェックに有効です。さらに、自分自身でも知らず知らず...いや、確信犯的にコピー&ペーストで開発してしまう事もあります。

P子「納期が近い時とか、ついつい、やりがちね」

 とはいえ、やはりきちんとオブジェクト指向で設計して開発することで、重複コードを『出来るだけ』排除すべきだと思います。

P子「デザインパターンにも重複コードを避けるパターンって多いものね」

 そして、重複コードの検出ツールも多数存在します。それだけ闇が深いのでしょう。

 PMDに関しては、今回で終了です。皆さん、お疲れさまでした。

 ほな、さいなら

======= <<注釈>>=======

※1 P子「終わりなのに続いているの?」
 P子とは、私があこがれているツンデレPythonの仮想女性の心の声です。

Comment(0)

コメント

コメントを投稿する