デバッグを必修科目にするべき理由

更新版: まずはここで私がコンソール ロギングでのデバッグを非難したり、無視しようとしているのではないということをはっきりさせておきたいと思います。コンソール ロギングは組み込み型プログラムやIDEがソースコードをスタックフレームに正しくマッピングできない場合、ブレークポイントが進捗を妨げてしまう場合等、様々な場合に使われます。要は他に適した方法がある時にコンソール ロギングを使うことを悪いと思っているのです。

プログラミングでは新しい機能を加える代わりに、コードのメンテナンスと問題の解決にそのほとんどの時間を費やされるということが常識になっています。また、デバッグを通じて問題を発見できてもそのバグの解決方法がわからないということが多いのです。またハイゼンバグやネッシーバグのような再現できないバグに遭遇することもありますが、通常はどこを探すべきかが全くわからない状態で、大規模なコードベースを相手に問題を見つけようとしているのです。

一般的にはコード関連の問題を修正する際には以下のようなステップに従います。(道のりは人によって違います)

  1. 問題について情報を収集する。
  2. 問題の再現方法を考え、再現してみる。
  3. バグの発生原因について仮説を立てる。
  4. 自分のコードを見直し、壊れた箇所を探し、できれば前述の仮説を変えてみる。
  5. 壊れたコードを見つけるまでステップ3と4を繰り返す。
  6. 解決策を考える。それ自体が難題ですが。

常識とは実はあまり知られていないものだ

今まで一緒に仕事をする機会があったプログラマーのうちびっくりするほど多くが前述のステップ3~5までをシステマチックに対応する方法を知りません。

彼らには正しいデバッグのワークフローがないのです。中にはワークフローが全然ないという人さえいるのです。

皆、コードのトレース方法、ブレークポイントを使ったりウォッチさえ使う方法を知りません。その代わりに彼らはconsole.logvar_dumpConsole.WriteLine ステートメントや他の言語でのこれらと同等のものを使いたがります。

初心者のデベロッパーは十分な経験がないため、彼らにとってこのアプローチは当たり前のものであり、はっきり言って予測されるものなのです。バグを修正する経験が増えれば増えるほどバグ修正が上手くできるようになるものですが、時折悲しいことに、何年もプロの開発者としての経験があってもコードをデバッグできない人に会ったこともあります。

ここにこそ問題があります。それは、開発者自らが正しい問題の対処法に関する十分な知識を得ようとしないことで結果的に自らの首を絞めているのです。またそうすることで、時間とお金がかかるだけでなく、気が張りすぎて長期的には健康的な問題を発生させ、神経衰弱に陥ってしまう可能性もあるのです。3日以上連続でバグ探しをすることになるとストレスが溜まる一方で、こういった状態はプログラマーに悪影響を及ぼすのです。

それでは、どうすればこの問題を解決できるのか、ということになりますが、私のお勧めするのは、コンピューターサイエンス、ソフトウェア エンジニアリングを始めとするプログラミングに関わる大学の専攻科目にデバッグ方法の学習課程を導入し、必須科目にするべきだと思います。誰もが問題解決の方法を知るべきなのです。

デバッグは実習しながら学ぶものというのであれば、そんなクラスを受けたらどんなメリットがあるのか?

私は6年生の時、放課後の一般向けコンピューター教室でデバッグの技術に触れました。それがきっかけとなりその先数年間にわたりこの教室から小さな天才児がTurbo Pascalを駆使したプログラミングの神様たちが生み出されました。私が問題に遭遇すると先生がいつもステップインステップオーバーの仕組み、ウォッチの使い方等など自分のコードをトレースしてエラーを見つける方法を教えてくれました。

この経験はクラスメートがデバッグの概念を知らずに苦しむ様を横目に見ていた、その後の高校と大学での学習に役立ちました。トレーシング方法を誰かが説明し実演した後にはクラスメートも宿題をうまくこなしていました。学校と大学の教師はデバッギングをプロジェクトと宿題に組み込もうとしていましたが、「自分のプログラムがうまく動かない理由がわからない時には、こうやってデバッグしてみなさい」というように的を射ていたとは言いがたいものでした。

そう、デバッグは経験しながら身につけるものなのです。あなたが何年ものプログラミングの経験を持っている人なのかもしれませんが、まだSafariを使ったリモートデバッグPhonegapアプリのように新しい技を見つけているかもしれません。

デバッグのクラス受講することでデバッグに触れる機会が与えられます。基礎知識を持っているプログラマーが増えれば増えるほどこの業界がより品質の高いコードを作り出すことができるようになるのです。問題をより効率的に扱う方法を開発者に教える必要がありますが、これは彼らのパーソナルな時間についても言えることなのです。「あ、何か問題が起こったみたい?でも、システマチックに問題の原因を見つけ、修復する方法を知っているから大丈夫。」

さらに、そのようなコースの名前は「問題解決法入門」といった高校レベルでさえ教えられるような抽象的なパターンや概念を教えるものでもいいのです。問題の扱い方のパターンを身につけることは誰にでも役立ちます。エンジニアリングや数学を中心とした科学分野全般ではパターンに基づいた問題解決法の影響を受けやすいのです。

それで、次は何を?

デバッグについてもっと学んで下さい。新しいヒントや技、パターン、ワークフローのショートカットなどを見つけて下さい。次回の投稿では特定のIDEツールの使い方、プログラムのトレース方法、そして問題のあるコードをみつけるパターンの使い方などについて深く掘り下げます。

それまでのためにデバッグコースでカバーすべきざっくりとしたアイディアの概要を以下にまとめました。

以下のリストを見てよくわからないトピックについて学び、スキル磨きに励んで下さい。これは誰にでも役立ちます。

サンプル: デバッグ手法コースの内容

  • コードがどのようにして実行されるのか(ラインごと、コールバック等)、しかしこれは他のプログラミング課程である程度はカバーされているものです
    • コールスタック
  • ブレークポイント
    • ブレークポイントのタイプ
      • 条件付きブレークポイント
      • 関数ブレークポイント
      • 外ブレークポイント
    • ライブラリ関数にブレークポイントを追加する方法
    • 低レベル デバッグにおけるブレークポイント(例:アセンブリ)
  • ステップの使用方法
    • ステップイン
    • ステップオーバー
    • ステップアウト
    • 継続
  • データのハンドリングについて
    • ウォッチ
    • オート
    • ローカル
    • REPL/式の実行
    • レジスタ
    • メモリ
  • マルチスレッド/マルチプロセス アプリのデバッグについて
  • 事後検討デバッグについて
    • ロギング
    • ファイルへ
    • リモートサービスへ
    • リモートロギング
    • クラッシュレポート
    • クラッシュダンプ
  • バグレポートについて
    • 読み方と提出
  • ベストプラクティスとパターンについて
    • 不慣れなコードでの問題箇所の特定
    • トップダウン/再帰的手法によるモジュラーシステムにおけるバグの発見方法
    • 不慣れなトピックに関する情報の見つけ方
    • ランダムなプリントステートメントを使うべき時
  • そして最も重要なのは練習を重ねることと、様々なIDEおよび言語を使った実例です

一言で言うと この業界全体、そして個人がさらに発展できるよう、できるだけ早く世の中のプログラマーにデバッグの基礎から上級までの概念について触れさせる必要があるということです。