師匠の話をしましょうか
私の師匠の話をしようと思います。全くの専門外から えぃやぁと、この業界に入り込んだ私を鍛え上げた師匠です。私はようやく当時の師匠の年齢に追いついたけれど、しかし師匠に遙か及ばないのです。
* * *
思えば、師匠は相当変な人でした。
朝は会社に来ないし、リーダの仕事である判子押しを新人だった私に押しつけちゃったりと、ハチャメチャな人でしたが、専務も社長も 師匠にだけは何も言えないという、マンガのような人でした。
曰く「眠いときは寝てから仕事する。それが一番効率的だ」。曰く「誰でも出来る仕事は新人にやらせても一緒だろう」。師匠は徹底的な合理主義者であり、常に合理的な最適解を出します。その前にタブーなんてのは全くなかったりします。ようするにハッカーだったのです。
私の会社は デスマーチが常態と化していいました。そのなかで師匠は、デスマーチを起こさなかったし、炎上しているプロジェクトは師匠の手にかかると鎮火しました。たとえ最悪の状況でも胴体着地はしてみせる。どんな危機的状況であっても コントロールは師匠の手の中にありました。私は師匠の仕事っぷりにすっかり痺れてしまったのです。
一方で会社はとても酷かったです。「同時に3つのプロジェクトを進めて初めて一人前だ」と言われ、皆複数のプロジェクトを掛け持ちしてました。定時で一つ、残業時間で一つ、休日で一つ。だから、緩急がなく常にピンチでしたし、一カ所で起きたデスマーチは森林火災のように一気に会社中のプロジェクトに広まりました。それでも、師匠の管理するプロジェクトチームだけは火災と無縁で、・・・その代わり同時に処理せよと放り込まれる炎上プロジェクトはどんどん増え、育てた戦力はそちらのチームに剥ぎ取られていきました。
しかしそんなやるせない状況下でも、師匠は 健全にプロジェクトを動かせるような工夫を絶やしませんでした。人手が足りないと言えば新人をつぎ込まれ、ようやく一人前になりだした3年目を目前にはぎ取られる。そんなサイクルを繰り返す。どないせいっちゅうんや、な状況下で師匠は、新人がいきなり戦力になって勝手に育つような仕組みと作ってしまうというハックをしていました。
要はコードが読めて書けばいいんでしょう?
例えば、C言語は サブセットでした。ループはwhileだけだったし、一行で一つの処理をすることを推奨されていた(これはデバッガ対策でもあったが)。文字列渡しは必ず &str_buf[0] のように配列を意識させる書き方を徹底していたし、ポインタは変数名に _ptr を含むなど、ポインタとして解る名前を付けるようにしていた、ようするにコードの字面を具現側に傾けるよう配慮されてました。コーディングスタイルは とにかくシンプルなルールになるように。どれもこれも よちよちあるきの新人のためのコーディング規約です。
しかし、極めつけはコメントで それは奇っ怪ながら非常に良くできた仕組みでした。たしか、こんな感じだったです。
/********************************************************** * 関数名:コンソール経由数値入力取得 * * 引 数: * query_msg 出力メッセージ(空文字のときは何も出力しない) * number_ptr 入力値の格納先ポインタ * * 戻り値: * OK 正常な数値入力を取得できた * NG 入力値不正 * * 注意: int型 範囲外チェックは行っていない * **********************************************************/ RESULT_TYPE ConsoleScanNumber( const char *query_msg, int *number_ptr ) { char input_buf[ CIN_BUF_LEN ]; /* 入力文字列取得バッファ */ char lf_chk_buf[ CIN_BUF_LEN ]; /* '\n'検出対象バッファ */ char *lf_ptr; /* '\n'位置ポインタ */ int convert_cnt; /* fscanfで書式変換した数 */ /* (1) 入力を促すメッセージを表示 -------------------------*/ if( query_msg[0] != '\0' ) { printf( &query_msg[0] ); /* query_msg を画面に表示 */ } /* (2) 入力値の取得 ---------------------------------------*/ /*(2-1) 標準入力からデータを取得---------*/ fgets( &input_buf[0], CIN_BUF_LEN, stdin ); /*(2-2) 標準入力のゴミを取り除く --------*/ memcpy( &lf_chk_buf[0], &input_buf[0], CIN_BUF_LEN ); while( TRUE ) { /* 改行文字が見つかったら ゴミ掃除終了 */ lf_ptr = strchr( &lf_chk_buf[0], '\n' ); if( lf_ptr != NULL ) { break; } /* 見つからない場合は標準入力の読み込みを続ける */ fgets( &lf_chk_buf[0], CIN_BUF_LEN, stdin ); } /* (3) 文字列→整数コンバート -----------------------------*/ convert_cnt = sscanf( input_buf, "%d", number_ptr ); /* (4) 関数の終了 -----------------------------------------*/ if( convert_cnt == 1 ) /* 書式変換された数が1 => 成功 */ { return( OK ); } else { return( NG ); } }
コメントがまるで擬似コード(!)。Cが読めなくても 処理の流れが読めます。リーディングはこれでOK。ではライティングは、というと、私はコードをコメントから書け、そしてコメントとコメントの狭間にコードを落とし込むのだ と言われました。コードをセパレートするコメントはたとえ構文上の文章構造がなくても、プログラムには常に構造があるのだということを意識させました(そのブロックにそぐわない処理をいれると直ぐ気づく)。
またセパレートされたブロック間のコードが大きくなったらそこをそのまま関数に分割しろと言われました。これは、(当時知らなかったけれど)構造化プログラミングです。このスタイルでコーディングをすると、自然に良い(スパゲティでない)プログラムが作れるようになる、そんな補助輪になってくれるコーディング規約です*1。
もちろん、このコーディングスタイルは、保守にべらぼうに工数がかかるし、冗長です。 なので普通の状況下では ナンセンスなのですが、しかし実際あの環境ではとても有効で、師匠以外のチームの平均社会人歴は 2年を割るような状況でも、私たちのプログラムの品質は高く、不具合もほとんどありませんでした。当時は当たり前だったけど、今思い返せばびっくり。
師匠の元で育った人材は社内的にも「優秀」のレッテルが貼られるようになり、師匠の弟子であることだけで一目置かれました。だから、私も、まぁつい天狗になってしまって、手痛い失敗をしたのですが、、、その失敗談は次の機会ってことで。(^^;*2
* * *
K のこと - Backnumbers: Steps to Phantasien を読みました。素晴らしい文章で、同時にとても懐かしかった。
K は以前よく <泥の中で一歩を踏みだす> 重要性を語っていた. デスマーチの混乱の中, 理想からほど遠い環境でいかに最初の改善を始めるか.
K のこと - Backnumbers: Steps to Phantasien
K が踏み固めた足元にある泥沼を私は見ていなかった. 道半ばに満足していた.
私は師匠を思い出す。あの果てしない底なし沼のなかで私に足場があったのは、師匠のおかげ。今、私は泥の中で足を踏み出すような仕事を未だに続けています。今でこそ結構うまく歩けるようになったもんだと自分でも思えるけれど、師匠の元を離れて初めて自分だけでズブリと沈んだ沼の感触を私は忘れられない。私は歩けると思っていたけれど全然歩けなかった。なくなって、初めて解るありがたみ。そんなもんです。
もう、師匠とあうことは無いでしょう。実は私は逃げ出した不肖の弟子で、連絡手段も今はもうありません。(風の噂には体をこわしたと聞きます。大丈夫かなぁ)。あの頃は逃げ出さないと死んでしまったから、その選択は後悔していないのですが、でも、今でも もっと長く師匠の歩き方を見ていたらなと思うことはあります。盗みたいと思う。だって私は、年齢しか当時の師匠に追いついていないから。