デバッグという基礎素養

経験の浅いプログラマーデバッグにてこずってるのって、 これと似ていて、 むやみやたらにクリックするのだけど、 自分の知ってるパターンに収束させることができない、みたいな。 これについては、経験を積めば、 自分の知ってるパターンが増えてきて、 バグだ、と思ったときには既に自分の知ってるパターンだから直せる、とか、 ちょっと試行錯誤すればパターンに落とし込めるとか、 そうなるんじゃないかな、と。

経験の浅いプログラマーがデバッグできない理由

については、コンパイラの吐くエラーが実は直接的が原因を示していない、とか、そういうレベルの話では実感だな、って思います。

「そうそう、コンパイラがこんなこと言うときは実際にはあんな事が起きてるんですよ」みたいな知識データベース。そしてコンパイラが検出出来ないタイプのバグについても、現象に「あれ?、どこかでみたぞ、これ」となる。そういう「良くあるパターン」の蓄積はデバッグのスピードアップに大きく貢献します。

正しい。けれど、それはそれとして。

根本的な問題として、「問題の切り分け」というのが出来ていないからデバッグ出来ないというのが、「デバッグができないこと」なのではないかと思います。


* * *


ただ闇雲に「試してみて」、たまたま上手くいったらデバッグ終了・・・というのは、プログラミングでもデバッグでもありません。不具合に遭遇したとき、なぜそのような動きになってしまったかを推論し、それを検証し、理解する。その上でどのように直せばよいかを組み立てる。それがデバッグです。

キースはこのような不意打ちには驚かなかった。先に述べたように、ロゴの環境のメーンステーの一つは、バグとデバグに関連した概念の集まりである。初めての試みがそのまま上手くいくとは思わない。「正しい―良い成績」「誤り―悪い成績」という基準で評価するものは居ない。むしろ「どうやったら直せるか」と問い、そして直すためには、何が起こったかをそれ自体の言葉で理解しなければならない。その上で初めて、我々の思うように実現させることができるのである。


デバッグの実際はマインスイーパーによく似たもので、グレーな世界を区分けて、区分毎に白黒ハッキリさせていくことで、白な領域を広げて黒を特定する作業です。「絶対に正しい」白で領域を一つ一つ塗りつぶして 疑わしい範囲を狭めていく、というやり方です。

だから、デバッグをやりやすすさには大きな前提条件があって、それにはプログラムがそもそも分割統治されているか(構造化されているか)です。構造化されていないスパゲティなプログラムの場合、白のエリアを広げることは非常に困難で、最早 場当たり的な勘での盲撃ちくらいしか手が無かったりします。

つまりデバッグが苦手という人は、コードの海がらバグを見つけ出す眼力が不足しているというより、そもそもプログラムをデバッグしにくい構造で作っちゃう事が原因であることが多いと思います。

しかし、この状況においてキースは何が起こったのか想像がつかなかった。彼のプログラムの書き方は、間違いを見つけるのを極めて困難なものにしてしまった。プログラムのどこにバグがあるのか?いったいどんな間違いが彼の意図したこととはまるで見当外れなものに変えてしまったのか。
彼の苦境を理解するために、「構造的プログラミング方法」として知られている別の手段と、彼のプログラムを比較してみよう。この目的は、プログラムを無理のない部分に分けて、それぞれの部分を別々に修正できるようにすることにある。キースの長い特徴のない命令の羅列ではバグを指摘することは難しいが、小さな部分を扱うのならばバグを閉じ込め捉えて理解することは容易だ。

だから、プログラムの上手な書き方とデバッグの巧さは決して別の技術ではありません。同じカードの裏と表、小さな理解できる規模に分割された見通しの良い構造を持つプログラムを作ることが、デバッグが出来るように成ることでもあるのです。

中学一年のロバートは、自分のプログラミング様式がこのように変わったことについて次のような驚嘆の声を発した。「見てごらん、僕のプログラムは皆、頭に入る大きさ(mindsized bites)になったよ。」そしてまた、こうつけ加えてこの比喩を強調した。「僕はプログラムには良く混乱したものだったけれど、今は、いっぺんに噛みこなせる以上は口に入れないんだ。」

Aha!


* * *


さて、先ほどから登場しているキース君やロバート君が出てくる文章は、実は「マインドストーム」からの引用です。

マインドストーム―子供、コンピューター、そして強力なアイデア

マインドストーム―子供、コンピューター、そして強力なアイデア


この本は子供の教育のお話です。

デバッグの技術はなにもプログラムを作る人達の、その為の技術ではありません。パパート先生は「マインドストーム」の第一章でこんなことを言っています。

成功や失敗を白か黒かと言う風に見る態度をこのように変える影響力は、コンピューターを「考えるための道具」として用いる要因の一例である。明らかにコンピューターを使って勉強しなければ優れた学習方法が得られないと言うことはない。「デバグ」の技術は、コンピューターの現れるよりずっと前から学習に長けた人達が発展させてきたものであることは確かだ。

教育にコンピュータを使うからデバッグを身につけるのではなく、デバッグの技術を覚えるためにコンピュータを使って教育をすべきと言っています。そうして覚えたデバッグの技術はコンピュータに限らない、子供達の「学ぶ力」となります。


何が言いたかったかを整理すると、

というただそれだけだったり。


で、最後に毒を吐くと、「大半の人間がデバッグできない」という状況は 情けない状況で、未来人から見れば、今の日本人が、文盲が大半だった時代に抱くのと同じような感想を抱いちゃうような(信じられない。誰だって教育を受ければ出来るようになるものなのに!..みたいな)、ちょっと悲しい状況だと思います。「向き不向きとか関係のない」が説得力を持つには、実際の教育の成功が必要です。残念ながら今はプログラミングもデバッグも向き不向きのある一部の人の専門的技術のように思われています。

全ての人が当たり前のようにデバッグする時代が早く来ますように。

余談

デバッグがどうにも苦手、と言う人は、ユニットテストを書く習慣をつけるといいと思います。わたし自身、仕事でユニットテストを書くようになったのは比較的最近なのですが、ユニットテストを書くようになって、それはもう恐ろしいほどデバッグが楽になりました。こんなに簡単でいいのかな、と思っちゃうくらいに。

予期せぬ何かの現象(バグ)が起きたとき、疑わしい周辺パネルのユニットテストを見ると、デバッガもprint文埋め込みもなしにもう白だということがハッキリしてしまうこと。いきなり黒パネルがだいたいどこだかハッキリ解ってしまう、絞り込まれた状態からスタートするので、ユニットテストを書くようになってデバッグがこんなに楽で良いのだろうかと思ってしまうくらい楽過ぎます。たとえるなら「デバッグしよう」と思った瞬間、オートでマインスイーパーのパネルがパパパパッと開けられていく感じ。

また、ユニットテストが書きやすいようにプログラムを作ると、良く分割統治された良い(理解しやすい)プログラムになっていることが多いです。と言う風に ユニットテストを導入すると良いサイクルがぐるぐる回って、凄くプログラムを書くのが楽になる。なのでもう、ユニットテストのない開発なんて考えられません。