まつもと ゆきひろ
(Yukihiro "Matz" Matsumoto)

 「Code Reading―オープンソースから学ぶソフトウェア開発技法」(毎日コミュニケーションズ発行,写真1)という本があります。私はこの本の監訳者ですから,やや自画自賛になってしまいますが,ソースコードの読み方を主題にした本はほかにはあまりありません。技法からツール,データ構造,アーキテクチャ,さらには実際にコードを読んで利用する実例まで紹介している網羅的で良い本だと思います。

写真1●「Code Reading―オープンソースから学ぶソフトウェア開発技法」(毎日コミュニケーションズ発行)
写真1●「Code Reading―オープンソースから学ぶソフトウェア開発技法」(毎日コミュニケーションズ発行)

 この本の「はじめに」で「達人プログラマー」として知られるDave Thomas氏は以下のように書いています。

 他人の作品を読まなかった偉大な作家,他人の筆づかいを研究しなかった偉大な画家,同僚の肩越しに技を盗まなかった腕のよい外科医,副操縦席で実地の経験を積まなかった767機長――果たして,そんな人たちが本当にいるのでしょうか?

 たしかにその通りです。ソフトウエア以外の領域では修行することとはすなわち,他の人の仕事をながめ,まずマネをして,そして十分力を付けてから自分の独自性を出すことです。空手ではこれを「守・破・離」と呼ぶと聞いたことがあります。

 この当然のことが,IT業界では必ずしも守られていない側面がありました。商用ソフトの世界ではソースコードは「飯のタネ」であり,広く見せることは想定外でした。商用ソフトでは,隠し持ったソースコードがすなわち財産なので,なかなかよそのソースコードを読むことはできません。ソフトウエア開発技術の多くは,それぞれのソフトウエア会社の中で口伝のように先輩から後輩へと伝えられてきました。

オープンソースの登場で,コードから学ぶ機会が増えた

 しかし,近年になって状況は大きく変化しています。ソースコードが公開されている「自由なソフトウエア」は,1980年代から「フリーソフトウエア」として知られていましたが,90年代末から「オープンソース」という新しい名前を得て,広く知られるようになりました。また,インターネットの普及により,以前よりもはるかに簡単にこれらの自由なソフトウエアを入手することができるようになりました。少し検索すれば,世の中に数多くのオープンソース・ソフトウエアを見つけることができます。オペレーティング・システム(OS),エディタ,オフィス・ソフト,ペイント・ソフト,開発ツール,ユーティリティなど,今やほとんどあらゆる種類のソフトウエアがオープンソースで手に入ります。

 これらのソフトウエアは,実行ファイルだけでなくソースコードも入手できます。ソースコードを読んで,そのソフトウエアがどのように実装されているかを,実際に使われている「生の」コードを通じて学ぶことができます。

 例えば,OSを考えてみましょう。OSの重要な使命はハードウエアの抽象化と資源の管理です。ハードウエアを直接操作するのは大変なので,OSがそれらに対する使いやすいインタフェースを提供してくれます。また,メモリー,ディスク,時計などの「資源」を複数のソフトウエアが競合せずに使えるように管理してくれます。これらの処理の本質はさほど難しいものではありません。例えば,OSの教科書としては古典の,Andrew Tannenbaum教授による「Operating Systems: Design and Implementation(「オペレーティングシステム 第2版 設計と理論およびMINIXによる実装」,プレンティスホール出版発行)」は,実例としてわずか1万2000行で実装されたUNIX系OS,MINIXを紹介しています。また,初期のUNIX実装を紹介した「Lion's Commentary on UNIX」(アスキー発行)という書籍は,UNIX V6のソースコードを解説していますが,それもわずか1万行というコンパクトなコードです。

 しかし,世の中で実際に使われているOSは肥大化の一方です。オープンソースOSとして有名なLinuxのソースコードの行数は600万行にも上ります。Windows XPのソースコードは公開されていませんが,一説には,Linuxよりさらに多く数千万行に上るということです。OSの基本的な部分はわずかな行数で実現できても,それを実用的なレベルに引き上げるには,その数倍,数十倍のコードが必要になるのです。ソースコードが公開されていないソフトウエアでは,こうした実践的な部分を外からうかがい知ることはできません。一方,オープンソース・ソフトウエアであれば,このような部分も含めて実際のソースコードから学べます。これを生かさない手はありません。

 万有引力の法則で有名なアイザック・ニュートンは,自分の実績について「私がさらに遠くを見ることができたとしたら,それは単に私が巨人の肩に乗っていたからだ」と語ったといいます。過去の資産があればこそ,その上に偉大な成果を積み重ねることができる,という意味です。私たちも,オープンソース・ソフトウエアが積み上げてくれたソースコードという知識を利用することで「巨人の肩に乗る」ことが可能になるのです。

「読む目的」をはっきりさせる

 オープンソース・ソフトウエアのおかげで,実践的なソースコードを隅から隅までながめ,学習できるようになりました。だからといって,目的もなしにただソースを読みさえすれば,誰でも優秀なプログラマになれるわけではありません。残念ながら,ソースコードは,小説,音楽,映画などのように,直接人間の感性に働きかけるものではありません。ソースコードは,人間とコンピュータの両方が理解できるように,プログラミング言語というやや特殊な形式で記述されています。ですから,普通の小説のようには読み下せません。数万行もあるソースコードを目的もなく最初から読み下してその中身をすんなり理解できる人はほとんどいないでしょう。ただ,ソースコードには小説のような物語があるわけではないので,必ずしも全体を通して読む必要はありません*1。むしろ,積極的に面白そうなところ,必要なところだけをつまみ食いして,先人の知恵を学べばそれで十分です。

 さて,ソースコードを読みこなすにはいろいろと必要なものがあります。最も必要なものはおそらく「目的」でしょう。何かを学ぼうと思ってソースコードを読むことで,効果的に読解し,知識を得ることができます。例えば「再帰下降構文解析の実装法を学ぶ」とか「この処理系がどのようにガーベジ・コレクションを実装しているか」とか「なぜこの処理系はこんなに高速に動作するのか」といったことです。何かを身に付けようという目的は,膨大なソースコードの中でどこを読むかということを決める指針になります。

 ソースコードを読む目的は,学習のためばかりとは限りません。例えば,ソフトウエアの保守やデバッグのためにソースコードを読まなければならないこともあります。仕事上の理由で他の人が書いたソフトウエアを保守しなければならない事態になることは珍しくありません。ソフトウエアを改善したり,機能を追加したり,バグを直したりするためには,目的のソフトウエアのソースコードを読みこなす必要があります。たとえ自分が書いたソフトウエアでも,しばらく時間が経てばその内容や背景などをすっかり忘れてしまうことも珍しくありません。ソフトウエア業界には「半年前の自分は他人」という「ことわざ」があるくらいです。ですから,自分の書いたソフトウエアでも,結局はコードを読む必要があります。

「読み方の戦略」を持つ

 たとえきちんとした目的を持っていても,やみくもにソースコードをさまよっていては目的を達成できません。コードの読み方の戦略にはいくつかありますが,私がよく使うものを紹介しておきましょう(図1)。

図1●ソースコードを読むための三つの戦略
図1●ソースコードを読むための三つの戦略

●落下傘方式

 目的を持ってソースコードを読むときに,プログラム全体を読む必要があることはまれです。実際には,何か知りたい知識が隠されている部分とか,バグを抱えている部分とか,全体からみるとほんの一部に過ぎないところを見つけ出し,その部分だけを読めば十分である場合のほうが多いのです。「落下傘方式」とは,そのような重要な場所を見つけ出して,その部分のソースコードだけを読解する戦略です。落下傘部隊が戦略上の重要ポイントにいきなり降下するイメージですね。落下傘方式の本質は,どの部分が重要であるかを見つけ出すことです。実例はあとで紹介しますが,検索が鍵になります。

●深さ優先探索方式

 ごくまれに,プログラム全体の流れを把握したいケースがあります。例えばLinuxの起動時の制御の流れを把握したい場合などです。このような場合には,プログラム起動時に一番最初に実行されるmain関数から始めて,呼び出される関数を次々にたどっていく「深さ優先探索」が有効です。これ以上他の関数を呼び出さない末端の関数まで来たら,今度は今までの経路を逆にたどって読解をはじめます。このようにボトムアップで読解することで「知らない関数が存在しない」状態で読解を行うことができ,効率的にソースコードを読むことができます。この方式は開発者の名前を取って「ひらメソッド」と呼ばれ,実際にLinuxソースコードの読解に用いられています*2

●デバッガ方式

 プログラムの状態は実行に伴ってどんどん変化します。ですから,プログラムを読解するといっても,プログラムの字面だけをたどっても理解できるとはかぎりません。ときには読解者は自分がコンピュータになったつもりで変数やオブジェクトの状態を想像しながら読解する必要があります。

 しかし,考えてみれば,我々が想像しなくても,どうせコンピュータはプログラムを実行するのですから,その実行の様子をのぞいてみることができれば,正確に実行時の状態を知ることができます。そのことを可能にしてくれるのがデバッガです。デバッガを使えば,プログラムを任意の場所で一時停止させ,そのときの変数の状態などを調べられます。デバッガはバグを発見するために作られたソフトウエアですが,ソフトウエアの動的な状態(実行時の状態)を知ることができるため,コード・リーディングにも有効です。