megamouthの葬列

長い旅路の終わり

消えたプログラマの残したものは

システム開発の佳境に、開発メンバーが突然出社しなくなってしまう。

携帯にも連絡がつかず、3日ほど音信不通になったので、さすがに心配になった上司が大家と共に自宅を訪れると、夕日が差し込む部屋の真ん中に、当の本人が何の表情も浮かべずにただ座っていたりする。

そういう事は大して珍しいことではないので、ある程度経験のあるIT業界人なら、同僚が「消えて」しまってもそれほど驚くことはない。


プログラマというのは、とかく「消えて」しまうものなのだ。と彼らは思っている。


「消えた」プログラマは、意識的にしろ無自覚にしろ自分の人生をちょっとばかり台無しにしながら、プロジェクトに虚無の穴を空けるわけだが、そうした「工程の穴」は他のメンバーが残業したり、派遣会社から来た代替の人員が埋めてしまったりする。ビジネス的には人月で数えられた我々の「数字」などというものはちょっとした帳尻あわせでなんとかなってしまうらしい。

消えたプログラマが残したものは、会社の立場から言うと、傷病手当の手続きとか、労災とか、そういう総務的な雑事は別として、特に何もない、と言えるかもしれない。





私が今ほど酒を飲んでいなかった頃、ちょっとした気まぐれで、あるシステム会社に常駐する仕事を請け負ったことがある。

PHPで組まれた開発途中の業務システムの引き継ぎ、というのがその内容だった。残り作業で言えば、2週間もあれば終わる内容に思えたが、依頼主であるシステム会社は納期として1ヶ月を設定してきたので、私はのんびりと会社員ごっこをするつもりで仕事を請け負った。

私がオフィスに出向くと、20代中盤ほどの女性が私の席のパソコンのセットアップをしてくれていた。

「ありがとう。これからよろしく」

と私が言うと、彼女は物怖じするような表情で言った。

「こちらこそよろしくお願いします。このシステム、元々は私が作っていたんですけど、手が回らなくなってしまって…」

依頼されたシステムは、全体の規模としてはそこそこの大きさだったので、私は彼女の若さに少し驚いたが、若く才能に恵まれたプログラマはそれほど珍しくもないと思い返した。

私は、割り当てられたパソコンに開発環境を整えると、早速依頼されたシステムのソースコードをざっと眺めることにした。


奇妙なコードだった。まず、既存のフレームワークは何も使っていなかった。ただ、独自フレームワークらしきものがかすかにあって、定数はconstant.phpというファイルにまとめられていたし、ログイン処理など共通の処理はcommon.phpに、またHTML表示部分はsmartyで完全に分離してあった。

まず奇妙なのは、その薄いフレームワークが無意味であるほど、あらゆる場面でコピー&ペーストされたと思しきコードが散乱していたことだ。

例えば、管理画面にログインしているかを判定している部分はこんな様子だった。

<?php
if(!is_already_logined($SESSION)){ /* 一般ユーザーとしてログインしていなければ */
   header("Location: ".LOGIN_URL); /* 一般ユーザーログイン画面へ */
   exit;
}else if(!is_already_logined_admin($SESSION)){ /* 管理者としてログインしていなければ */
   header("Location: ".ADMIN_LOGIN_URL); /* 管理者ログイン画面へ */
   exit;
}

このコードが、管理画面系のPHP全てにコピーされているのである。

is_already_logined関数もis_already_logined_admin関数も、common.phpにあった。ようするに、これらを一つの関数にして、

<?php
check_admin_login();

と書いたり、もっと普通の発想で言えば、管理画面系のURLルーティングを単一のファイルで行って、そこでログイン処理を行ってしまうべきだ。そう書いたほうがいい理由は省略するが、つまるところ、無意味なコピー&ペーストであり、それによってソースコードが必要以上に読みにくく複雑になってしまっているのであった。

なんだこりゃ?と私は思ったが。このへんの事情に足を突っ込んでも報酬が上がるわけではなかったので、次に共通して読み込まれているcommon.phpと、constant.phpを私は開いた。


私のEmacsがフリーズした。


constant.php2万行近くあるせいだった。constant.php

<?php

//...

define('TXT_RECORD_NOT_FOUND','レコードが見つかりません');


と言った有様で、ようするに、全ての日本語のメッセージがconstant.phpに埋め込まれていた。

堪りかねた私は、前任者である彼女に理由を尋ねた。何故、日本語メッセージを全て定数にする必要があるのか?何度も使用されるメッセージを共通化したいなら、gettextでリソースファイルに分離するなど他の方法はいくらでもあるだろう、と。

それほどの剣幕で迫ったつもりはないが、彼女は困惑顔で返した。

「さあ?なんでなんでしょうか?私が受け持った時には既にそうなっていたので…」


私は、全てを理解した。そうか、プログラマが「消えた」のだ。

静かに席に戻った私はEmacsPHP解析モードをOFFにして、シンタックスハイライトなどの余分な動作を切り、カーソル移動できる状態にして、もう一度common.phpとconstant.phpを最初から見ることにした。

ファイルの最初のほうはまともであった。すなわち、共通に使用される関数は簡潔に(当時の視点でさえ時代遅れの構造化ではあったが)まとめられており、constant.phpもほとんどはシステム動作に不可欠な定数の定義に使用されており、唯一の日本語メッセージは、共通のエラー文字列だけだった。

もはやファイルのタイムスタンプを確認するまでもないだろう、と私は思った。おそらくは、このシステムは構築の初期、ある程度はまともに作られていたのだ。しかし、そのまともに作ることのできるプログラマは「消えて」しまった。

あとを引き継いだ彼女は「消えた」プログラマほどの技量はなかった。彼女は「消えた」プログラマが残したフレームワークを理解することもできず、ただ、ソースコードを模倣した。

エラーメッセージがconstant.phpで定義され、テンプレートから引き出されている。ならば、メッセージは全てそうしなければならない。と彼女は考えた。日本語が表示される度、彼女はconstant.phpを書き足す。あるいは、二つのファイルで呼び出される関数が必要となったならば、common.phpに書き足す。長い孤独な開発期間の間、彼女をそれを繰り返し繰り返し、やり続けたのだ。

「消えた」プログラマがいたならば、どこかで自分のアーキテクチャが破綻することは明白だと考えただろう。彼女の作業は止められ、メッセージはgettextのリソースになり、common.phpは複数のクラスに分割されたであろう。

だが、彼は消えてしまったのだ。彼女に何も告げることもできぬ場所に。



「まるでカーゴ・カルトですね」

と、依頼主である彼女の上司に進捗を尋ねられた私は、正直にそう言った。その会社の会議室には灰皿が置いてあったので、私は遠慮なく煙草に火をつけた。

「ようするに、あのシステムを最初に作った白人は、ミクロネシアの奥地に飛行場を作ったんですよ。後任の彼女はそこで飛行機を初めて見た。そして、白人が去った後、彼女はあなたに飛行機を作るように言われたわけです。」

戸惑う上司の前で、紫煙を吐き出す。

「やり方は教わっていない。ソースコードしか手がかりはない。だから木の枝や藁で、無線機や、滑走路を作って、飛行機を呼ぼうとしているんです」

消えたプログラマソースコードを残す。残された者は好むと好まざるとに関わらずそのソースコードに書かれた「思想」を見ることになる。自らの「思想」を持たない者は、それを個人の「思想」としてでなく、「信仰」として受け止めてしまうのかもしれない。


長い沈黙の後、苦虫を噛み潰したような表情で上司は言った。

「システムは…完成できますか?」

「まあ、飛行機は呼べますよ。でも、彼女が作った偽物の無線機を作り直すつもりはないので、そのつもりでいてください」


私は、これ以上constant.phpを肥大化させないよう、メッセージはそのままテンプレートに埋め込むことにした。そもそも多言語対応する予定もないのだ、gettextを使うまでもない。同じようなメッセージが出る画面は、共通部分のテンプレートを分割してincludeするようにした。

新たな定数や共通関数は、constなクラス変数、静的なクラスメソッドとして定義した(実働環境のPHP名前空間をサポートしていなかったのだ)、そして、関連するファイルでだけそのクラスファイルを読み込むようにした。こうしておけば、これ以上、悲惨なコピー&ペーストや長大なconstant.phpを書き足さなくていいようにしたつもりだった。


1ヶ月後、私は仕事を終えた。自分が書いた部分にバグがないことは確信していたが、それ以外は知ったことではない。私もまた、その会社から「消えた」プログラマとなったわけだ。



最終日、私物を鞄に詰め込んで、私は、彼女に別れを告げた。

「ありがとうございました。あのシステムを書くの、本当に辛かったんです」

と彼女はその時、やっと微笑んだ。


おこがましいと自覚しながら、私は、自分が新たに書き足した「思想」が、その後を引き継ぐであろう誰かに「信仰」されるのではなく、糧となってくれることを、願わずにはいられなかったのだった。


レガシーコード改善ガイド

レガシーコード改善ガイド