ある中級プログラマの告白

私は中級レベルのプログラマです。

基本を理解するのは得意です。過去の失敗をきちんと分析できるくらい経験を重ねていますし、もっと知るべきことは山ほどあることも分かっています。

特筆すべきは、自分で身につけるべきことを知ったうえで、それを吸収しようと積極的かつ精力的に取り組んでいる点でしょう。

プログラマとしての能力は平均的なものに過ぎないと、心から納得するまで時間がかかりました。今では、よく理解できないままに誰かの意見を受け売りする必要など感じていません。知らないことがあっても、それを他人に悟られるのは怖くありません。

でも以前は違いました。信じられないかもしれませんが、私はかつてプログラミングの達人だったのです。

自分の能力を誤って評価していたのは、比較的孤独な環境でスキルを学んだためでしょう。当時はコンピュータを持っていることさえ、ちょっと特別なことでした。使い方を知っているとなれば、なおさら特別です。

自己評価ですが、私は知識も経験も豊かなプログラマでした。10代の終わりにはC++、Pascal、C#、JavaScriptでプログラムを書いていましたし、これはかなり自慢ですが独自のeコマースサイトをPHPでゼロから構築したこともあります(詳細は後ほど)。

でも実際には、”Webサイトに詳しい友達の息子”に毛が生えた程度だったのでしょう。他のプログラマとは交流がなかったので、比べる対象といえば周囲の人間だけでした。彼らはコンピュータと格闘することもなく、せいぜいInternet Explorerの画面にスパムのようなツールバーが5本も表示されて、表示領域が狭くなったと困っているような人たちです。よく「インターネットが壊れた」なんて言い方をする人たちがいるでしょう?

私がなぜ実力を過信するようになったのかをお話します。

ことの始まり

9歳の頃、我が家のテレビはイギリスの標準4チャンネルでした(5チャンネルになる前のことです。よく我慢していました)。でも友達の家には衛星テレビが導入されており、あの圧倒的なチャンネル数に憧れました。衛星放送受信アンテナ(”サテライト”と呼んでいました)さえあれば、Q V Cやユーロスポーツをいつでも見られるのです。

私は才能の芽生えをわずかに感じつつ、自分のサテライトを作ろうと決意しました。まず開いた状態の傘と、銅のラジオケーブルを用意します。ケーブルの一方を傘の金属の柄につなぎ、反対側をテレビアンテナ用のコンセントにつなぎました。お分かりのように、この設計には少々欠陥があったため、期待通りの成果は得られませんでした。でもこのエピソードは、私の幼少期から青年期の特徴ともいえる技術への飽くなき野心をよく表しています。私の知る限り、サテライトを作ってやろうと考えた者など周囲にはいませんでした。

数年後、父が14.4kモデムを事務所に導入します。これを機に、私はいち早くインターネットを使い始めました。ある土曜日の午後は、flaming Manga logo のgifファイルがロードされるのを待ち続けていました。アニメgifの次のコマが表示されるまで1分ほどかかっていた頃です。Netscape Composerで、自分のWebサイトを作ったこともあります。

インターネット技術の知識がなかったので、自作のhtmlファイルをローカルに保存し、いつになったらネット上に公開されるのだろうと不思議に思っていました。この程度のささいな失敗はあるものの、私の知る限り、自分のWebサイトを作った者など周囲にはいませんでした。

13歳になる頃までには、自分の才能の暗黒面を発見します。私は数人の友人と、『Jolly Rogers Cookbook』で武装し、90年代半ばのイギリスを支えていた技術基盤と道徳基盤に揺さぶりをかけ始めました。フリーキング(電話システムへのクラッキング)が得意だった私たちは、手持ちの音響カプラを使ってICQで知り合ったアメリカの女の子たちに公衆電話からタダで国際電話をかけ、構内電話交換機でボイスメールボックスのセットアップまでしました。でも学校の勉強やスケートボードのおかげで、悪事をエスカレートさせずに済んだのです。あのまま突っ走っていたら、普通にナパーム弾を作ったり、政府のネットワークをハッキングしたり、素手で人を殺したりしていたでしょう。

自分たちの力を限界まで探ることはしませんでしたが、音響カプラを持っている者など誰もいなかったのです。

こうしてあらゆる技術を使って冒険や失敗を繰り返しましたが、まだ何かが足りませんでした。”サテライト”のエピソードでお分かりのように、私の場合、実際の能力よりアイデアの方が何歩も先を行きます。頭の中身を外の世界に取り出す手段が必要でした。

イマジネーションとリアリティを直結するインタフェースを求めていたのです。

F**kジェネレータ

真のターニングポイントは、14歳の頃に訪れました。『PC Plus』という雑誌にBorland C++ Builderのフルバージョン入りCDが付いていたのです。親切なことに”hello world”のチュートリアルもあったので、インストールしたあと慎重に指示に従いました。

まさに、これだったのです。眼前に新しい世界が開けました。私のイマジネーションを閉じ込めていた物質世界の制約が消え去ったのです。創造性が解き放たれ、頭の中にある壮大な構想が現実になる時がきたのです。この新たなツールにふさわしい崇高なゴールは何か?もちろんF**kジェネレータです。

F**kジェネレータ(fgen.exe)はシンプルかつエレガントなコマンドラインプログラムで、初めて”hello world”を超えた、私の成長の証です。実行すると数を入力するようユーザにプロンプトが表示されます。nと数字を入力すると文字列”f**k”がn回出力されます。最後に、実行を繰り返すか中止するかの選択肢が表示されるというものです。使う機会は若干限られていましたが、それでも一度味わったこのパワーに夢中になりました。プログラマならお分かりでしょう。たとえシンプルなタスクでも、マシンが自分の命令に従ってくれた、あの喜びにハマったのです。プログラムが動き、自分はその動かし方を知っている。プログラムは自分の命令どおりに動くしかないのです。

それから少し経って『PC Plus』にフルバージョンのBorland Delphiが付いてきたことがありました。私はこれを使ってF**kジェネレータをアップグレードします。Windows GUIを使って、カラフルでびっくりするような”F**k”が、ランダムに生成されるようにしました。学校で他の子たちがプレイステーションをしている間に、私はそれよりずっと有意義で創造的なことに挑戦していました。そう、f**kを生成していたのです。

この時すでに、自分は大きなことを成し遂げる運命なのだと、はっきり見えていました。実力を世界中に知らしめる時がきたのです。

私の最高傑作

90年代後半、私はある会社のwebサイトを作りました。小規模ながら通信販売で事業を拡大しつつある小売業者のサイトです。当初は、カタログをコピーしたような静的ページが少しあるだけでした。フレームセットにナビゲーションメニュー、サイトの訪問者数を示すお決まりのカウンタといった程度です。

そのうちサイト経由の問い合わせが日増しに増えてきたため、実験的にeコマースの機能を加えることにしました。恐ろしくひどいパッケージから普通にひどいパッケージまで、既成のものをいくつか使って、実験を繰り返しました。最初のバージョンではCGIスクリプトをいじりまわし、ほぼすべてのユーザインタラクションで<select>要素の使い方が妙なことになっていたのを覚えています。その後のバージョンは、フレームセットとJavaScriptでできたモンスターのようでした。JavaScriptベースのアプリケーション機能が推奨されるよりずっと前の話です。別のバージョンではMicrosoft Accessのデータベースも使いました。

最後には、平均レベルかあるいは堅実なオンラインショップを作るには顧客ソリューションが必要だと理解するまでになりました。fgen.exeやその後継版、この頃までに自作したwebサイトなどから過去の成功を振り返ってみて、良いサイトの例を見つけました。
Manic Street Preachersのギター用TAB譜をアーカイブしたwebサイトです。
私が作ったサイトで評判が高く、”Manics Web Ring”(ウェブリングは覚えていますか?)にも登録されました。いよいよ実力が試されます。自分の手でゼロからサイトを構築するのです。

当時、オープンソースのフレームワークが存在していたかどうかは知りませんでした。でも自分なりの計画があったのです。PHPとMySQLの本を買い、新サイトを作りながらこの2つを学び始めました。

運良くその本には、シンプルなショッピングカートのアプリケーションがサンプルプログラムとして特集されていました。サイト構築に必要な部品がすべて掲載されていたのです。category.phpを使えば、全商品をカテゴリに分類してリスト化できますし、product.phpを使えば、商品の詳細や”カートに追加”ボタンを表示できます。そして一番のポイントはcart.phpです。まるで魔法のようなプログラムでした。これを組み込めば、商品の購入手続きができるのです。

私は慎重にサンプルプログラムを打ち込み、すばらしい最先端技術をすべて忠実に実装しました。具体的にはデータアクセスに役立つmysql関数や、クエリを作成する文字列連結、関数を記述しておくfunctions.php、そしてサイト全体に一貫性を持たせるためのheader.phpやfooter.phpです。高速処理が可能な手続き型コードを選び、オブジェクト指向アプローチ(これが意味したものすべて)の巨大なオーバーヘッドを回避しました。私のスキルは飛躍的に向上していったのです。

しかしコードはシロアリの巣のように入り組んでいきました。追加した機能は四方八方に分散しています。追加したのは顧客アカウント、商品の評価、購入履歴、ポイントシステム、クーポン、キャンペーン、履歴、A /Bテスト、支払い情報の暗号化といった機能です。まるで互いに依存しあいながら無秩序に広がる迷宮のようで、形もサイズもバラバラな関数の群れがcart.phpというハブを中心にぐるぐる回っているようでした。

8ヵ月もの間、ひたすらコードを書き続けてついに完成します。

賢明な皆さんなら、私のサイトにとんでもないトラブルが起きたと予想しているかもしれません。でも残念ながら、その予想はハズレです。何とサイトは問題なく動いたのです。

最悪の仕事

私のアプローチを”最悪の仕事”と題しましたが、実際にはサイトの出来は上々でした。間違ったチュートリアルやアンチPHP派のブログに書かれていたことまで何でも試したのですが、それでも動いたのです。私のコードはスパゲッティコードだった? イエス。データやルーチンの名前のつけ方はバラバラだった? イエス。プレゼンテーション層がビジネスロジック層と混合して…いや、融合していた? イエス。マジックナンバーやグローバルデータを多用していた? これもイエス。

当時の私にとってオブジェクト指向アプローチは、数多く存在する無用なオーバーヘッドやボイラープレートでしかありませんでした。自分の考えを裏付けてくれるような誤った情報も信じていたし、自分のプログラムに対するテストも完璧だと思っていました。と言っても何度かクリックして問題なさそうならリリースする、といった具合でしたが。(奇抜で複雑すぎる)アーキテクチャがあることは何となく気づいていましたが、それでも自分のプログラムは(恐らく最速で)非の打ち所はないと思えたのです。

自らの素手と知恵でフル機能のeコマースサイトを作り上げ、それが問題なく稼働している。この事実こそ、私のコーディングが間違っていなかったことの証しです。サイトは順調に動き、さらに拡大していきました。

当時の私には、Amazon.com を作ったプログラマと私の実力に大差はないと思えました。もちろんAmazonの方がずっと大規模です。でも私のサイトだって規模を大きくしようと思えば、問題なくできると思っていました。何といっても私のサイトは非常に高速な、手続き型のアーキテクチャを備えているのですから。

この時点で、私のプログラマとしての成長は頭打ちになりました。学ぶ意欲がなくなったのではなく、学ぶ必要性を感じられなくなったのです。問題なく動くものを作り上げてしまったら、それ以上やっても単なるオマケにしか思えませんでした。

現実世界に戻る

残念ながら、この状況は数年間続きます。その間、サイトに関しては片手間で対応し、1日の大半はまったく違う分野の仕事をしていました。しかし数年間の保守作業と、たまに新機能を追加しているうち、サイトを構築した時の判断ミスに気づき始めます。ソースファイルのどこに何が書いてあるか、探し出すだけでかなり時間がかかるのです。それにサイトに手を加えると、まったく無関係な箇所でマイナーバグが多発しました。私はこのことに不安を感じ始めます。

完全に学習をストップしていたわけではありませんが、業界の動きには追いついていませんでした。例えば私の使ったmysql関数のリスクを知ったのは、何とPHPからmysql関数のサポートが外されると決まった段階でのことです。ずっと自分の作ったルーチンは隙がなく機密性も高いので、リスクを補って余りあるものと信じていました。様々なSQLインジェクションをあらゆる入力フォームでテストしてみましたが、やはり完璧だと思えました。

ところが昨年のある日、サイトがダウンしたとの緊急連絡が入ります。どこをどう操作してもHTTP 500-内部サーバエラーのメッセージが表示される、とのこと。その後ホスティング会社の技術者がエラーを解決し、無事にサイトは復旧しました。あとで分析したところ、エラーの原因は新種のSQLインジェクション攻撃によるもので、私も初めて見る類のものでした(SQLインジェクションに関するチュートリアルでも見たことがありません)。

ついにうわさに聞いていた最新のPDOとやらに、乗り換える時期がきたかと観念しました。

突然のひらめき

データアクセス関数をすべて書き直そうとした時、私は事の重大さに気づきます。事態はかなり深刻であり、深刻になった理由まで分かりました。

その理由は、関数がいたる所に散らばっていること、わずかな変更でもどんな影響が現れるか予測できないこと、コードに一貫性がないためインスタンスごとの結果にチェックが必要なこと、大部分のコードは他と密接に連携しており、一部を変更すれば破たんする可能性もあること。こうした理由から修正は面倒になるだろうと予測したのです。要するにこの雑然としたコードは、それまでの悪癖と理解不足の産物であり、今になってしっぺ返しを食らったのです。

自分を正当化するために言い訳をするか無知を装うかとも考えましたが、そうした衝動もなくなりました。間違っていたと認めるしかなかったのです。私は自分で思っていたほど才能あふれる優秀なプログラマではなく、何年もやり過ごしてきただけの偽者でした。

自分の愚かさがくっきりと浮かび上がり、私のエゴはひどく傷つきました。でも同時に大切な教訓を得たのです。身をもって、物事には正しい方法と間違った方法があると学びました。好みや流行に影響されるのでも、強力な主張をする人に左右されるのでもありません。正しい方法は実社会に影響を与え、皆さんの人生(そして皆さんのコードを利用する人たちの人生)をより良くしてくれるでしょう。一方、間違った方法はストレスを生み、時間の浪費につながります。”正しい方法”が何を指すのか気になるでしょうが、この難題に言及するつもりはありません。ただ自分のやり方は正しくなかったと言っておきます。

本当の罪

私はPDO を実装し、同時にPHP Unitを初めて導入しました。でもこの種のコードを追加するとユニットテストも必要なので、もうやりたくありません。

最近の私はというと、自分を奮い立たせ、意識的に新しい技術を学ぶようにしています。例えばプログラマの必読書を読み、ブログをフォローし、ポッドキャストを聞き、カンファレンスの動画を見たりしています。また地元のユーザグループに参加して、時々スピーチをすることもあります。最新技術を学びたくて、別のプロジェクトにも取り組んでいます。正しい方法を学ぼうと努力しているところです。

こうしたタスクに取り組んでいるプログラマにとっては好都合な要素もあります。プログラミングという試みは、完全に観念的な行為であるという点です。つまり多くの分野には物理的制約がありますが、プログラミングの世界にはありません。制約になるのは自分自身だけです。

ある名言で記事を締めくくりましょう。この記事の文案を練り始めた頃、スティーブ・マコネルの著書『Code Complete Second Edition』を読み終えるところでした。この本の825ページに書かれていた言葉には、記事を書こうとした時の私の心情がそのまま表現されています。ここまで数千語を費やしてきましたが、マコネル氏はたった2文にまとめました。

初心者や中級者であること、リーダーではなく優秀なプログラマであることは罪ではない。本当の罪は自らを向上させるすべを知ったあとも、初心者や中級者の立場に甘んじていることだ