デバッグする人にやさしいコードはあるけれど

http://uupaa.hatenablog.com/entry/2012/02/03/232243

(ε・◇・)з 分かりやすいコードは、ステップ実行もしやすいのです!
(ε・◇・)з ループの先頭に、滅多に通らない大きな塊を配置するのはダメなのです!
(ε・◇・)з ポチポチする毎に画面がスクロールするのは、余計なストレスなのです!

気持ちは分からなくもないけど,そういう理由で条件分岐の順番を変えるのは,自分はあまりお勧めしない.

条件分岐の書き方は「コードの読みやすさ」とか「バグの出にくさ」などで決めるべきであって,「ステップ実行しやすいから」というのは本質じゃないと思う.*1 *2

それから,発生条件が分かり難い場合はその条件分岐を通る条件も記述すべきですね.たとえば「この画面の初回呼び出し時かつDBMSのAカラムが空の時に,メールアドレスのフィールドに入力された文字列が100文字を超えた時だけ通る」みたいな感じ.*3


最初はてっきり,

  • 条件分岐の数自体を減らす.得に分岐をポリモフィズムに置き換える.
  • 事前条件/事後条件をキッチリ定義し,文書化する/メソッドコメントに記述する.
  • NULLを使わない.たとえば空文字列や長さ0配列を使う.
  • 不変オブジェクトを使う.
  • toString()をオーバーライドする.
  • タイミングに依存するコードを記述しない.
  • 防衛的プログラミング.
  • デバッガよりロガーを使う.

みたいな話かと思ったが違った.*4

Effective Java 第2版 (The Java Series)

Effective Java 第2版 (The Java Series)

  • 多くの方は難解なコードを目にした時に、とりあえずステップ実行を繰り返すのです。
  • そのコードをより深く理解しようとした人が、コードを眺め、次に取る行動の1つがステップ実行なのです。

それは強引すぎる気がする.

もちろん手段の一つとして利用するのは否定しないけど,仮にそれで理解できた「つもり」になったところで,プログラムの本質を理解できることはまれだろう.*5


通常ステップ実行で実行して理解できるのは,ある特定の初期条件(通常は正常系)の単一の処理だけ.ところがデバッグしにくいコードというものは,異常系の処理がスパゲッティになってたり,異常系の初期条件が無数にあって,しかも条件分岐の通る組み合わせによって処理が全部違っていたり,さらにはそもそも異常系の処理が書かれていなかったりする.そういう「デバッグしにくいプログラム」に対してはステップ実行は無力なのです。ステップ実行でプログラムを理解した「つもり」になるのも,ステップ実行でデバッグできるつもりになるのも,本当にデバッグしにくいプログラムをまだ見た事がないから言えるんじゃないかな.

http://b.hatena.ne.jp/entry/uupaa.hatenablog.com/entry/2012/02/03/232243

  • id:katzchang ステップ実行など、とうの昔に忘れたわい。

「忘れた」は言いすぎでも,Javaくらいの言語だと出番はほとんどないんだよね.むしろデバッグの方法を勉強した方が効率的かも.

このブログ主はJavaScriptの人なのかな?だとしたら,デバッグのスタイルはそういうものなのかも.それと同時にJavaScriptだからこそ,記述する順序はそういう理由で決めちゃいかん気がする.*6

  • id:r-west 同意しつつも、そんなに長いブロックは別の関数に切り分けませんか?と思ってしまった

同意.これも結構重要.

  • id:suginoy i == 5の方がi != 5よりわずかに読みやすい気がするのでちょっと例として微妙な気が。「ループの先頭に、滅多に通らない大きな塊を配置するのはダメなのです!」

実際には,そういう「微妙な例」の方が遙かに多いと思います.だからこそこの「デバッグする人に優しいコード」は実践的/実用的とは思えませぬ.

*1:昔はパフォーマンス上の理由でも分岐処理の書き方を変える必要は一応あったけれど,最近はCPUレベルやVMレベルの最適化のおかげで,まず無視できるレベルだと思う.

*2:コメントでも突っ込まれてたけど,ステップ実行はデバッグにおいては脇役だという問題もある.

*3:これはサンプルコードだから書いてないだけ,だといいなあ...へたくそなコードは,その条件分岐に到達するまでの条件を探すのに苦労したりするのだよ.

*4:goto文を使わない,グローバル変数を使わない,一文字変数はループカウンタの様なテンポラリな場合を除いて使わない,とかとかもあるけど,さすがに常識だよね...

*5:っていうか,そういう意味で処理をトレースするつもりなら,ロギングやユニットテストの方が便利だし...

*6:ちなみに例の本のKindle版も出てた.さてどうするか. http://www.amazon.com/dp/B006PW2URI/