プログラマーの実証主義について

プログラマーには「実証主義」とも呼べる態度がある。何もかも実際に動かしてみて、それから判断するという考え方。

例えば、システムのパフォーマンス改善をするためにはまず、現状を計測し、ボトルネックを明確に特定しておくことが当然のプロセスである。そうしなければその改善プロセスは何を目指してるのかわからない曖昧なものになってしまう。

この考え方はおそらく、ほとんどの場合において正しい。

理論値はいつでも間違っている可能性がある。特に、日常的なシステム開発では、小さな設計や実装上の意思決定が連続して行われる。それぞれの意思決定が少なくとも実用に見合う目的を満たしているかを判断するには、実際に動いているものを計測するのが最終的には最も客観的・正確である。チームでの議論もしやすいだろう。

一方で、いつでも実証に頼ろうとするのは思考停止なのではないか?と思うことがある。

例えばあるメソッドを実装する方法(アルゴリズム)が二つある場合、どちらの方がパフォーマンス的に優れているかは、ロジックの流れを計算すればわかるはずであるが、間違った実証主義=単なる面倒臭がりに陥っていると、コードを書いて計測して比較すればいいじゃん、ということになってしまいそうだ。ある意味考える必要がないので、楽である。

今のような例はすごく小さいが、こういった姿勢が長い目で見てプログラマーの成長の限界を決めてしまう可能性があるんじゃないか。

「怠惰」はプログラマーの三大美徳の一つと言われているが、上記のような態度はどちらかというと「考えること」に対する怠惰であり、理想である「手作業を減らすために徹底的に考える」態度の真逆だ。もっと簡単に言えば、こうした態度は「実装してみないとどうなるかわかんない」「ダメだったら一から実装しなおす」という非効率なプログラミングを生み出してしまうんじゃないだろうか。

つまるところ、「形にしてみないとわからない」という状態。これがシステムを作る上でどんなに障害になるか想像するのは難しくない。システムの設計なんていうものは、「形になる前にどれだけ精緻に考え込むことができるか」によって開発上の出戻りを減らせるものだし、それができなければ大規模な開発はできないだろう。いつも「バグが出るまで問題がわからない」という態度になりかねない。

しかし、いつでも実装する前に細かいところまでしっかり考えてから手を動かせばいいかというと、問題はそう単純ではない。

例えば、成長過程のプログラマーにとっては「まずはとにかく形にしてみる」ことが何よりも大事だったりする。そして、例えば2つの実装方法に差があるのであれば、どうしてそうなったのかを考え、実験によってそれを確かめる。その繰り返しで成長していくというのが一般的な流れだと思う。

つまるところ、やはりプログラマーの実証主義は正しいのだ。最終的には実証してみないと判断ができない。しかしその一方で、「考えればわかる」ことについては怠けずにしっかり図にするなりして考えて、できるだけ手数を減らす努力をすることがすごく大事だと思う。

より具体的なアクションプランとしては、

  • 実装する前に、時間を決めた上で徹底的に考える。
  • 決めた時間が過ぎてもわからないことに関してはとにかく実装してみる
  • 実装したものに対して「なぜそうなるのか」を考え、検証を重ねる

ということになると思う。まあ要は「考え続けることをやめない」ということでしかないけど。

該当するテストファイルが存在するかを判定するシェルスクリプト

当初の動機は、「Railsのモデルのまだ生成してないテストファイルを一括で生成する」こと。
とりあえず存在するか判定してテストファイル名を出すところまではやった。

ただファイル名からクラス名を割り出すところまでやるのはRailsのclassifyとか使った方が楽なことに気づき、このあたりでやめることにした。

#!/bin/sh

files="./app/models/*"
for filepath in $files; do
    #echo $filepath
    filename=${filepath##*/}
    without_extension=${filename%.*}
    path=${filepath%/*}
    extension=${filepath##*.}
    test_filename=${without_extension}_test.rb
    testfile_path=test/models/${test_filename}
    test_class_name=

    #echo "filename: " ${filename}
    #echo "without_extension: " ${without_extension}
    #echo "path: " ${path}
    #echo "extension: " ${extension}
    #echo "test_filename: " ${test_filename}
    echo "testfile_path: " ${testfile_path}
    if [ -f ${testfile_path} ]
    then
        echo "Found"
    else
        echo "Not Found"