こないだは英単語をローマ字読みするアルス族の話を書きましたが、今度は冗長なコードを書く人達のことを書きます。これも複数の会社で見かけた病気です。
これは友人から聞いた話です。つい最近、ある会社で事故が起きました。ログ(プログラムの出力の記録など)を調べていて起きた事故です。ログのファイルは末尾が .log という拡張子がついています。そのログから再起動(reboot)している個所を見つけ出そうとして、次のコマンドを打とうとしたそうです。
cat *.log | grep reboot …(1)
左の cat というのはファイルの中身をそのまま出力する命令で、真ん中の | はパイプと言って、左側に書かれたコマンドからの出力を右側のコマンドに渡してやることを指定します。右側の grep というのは入力された物から指定されたパターンを拾い出すコマンドで、grep reboot と打つことによって、rebootが入っている個所を拾い出すことができます。つまり、上のコマンドはログから reboot している個所を拾い出すためのコマンドと言うことになります。
ところが実際に打ちこまれたのは次のコマンドです。
cat *.log | reboot …(2)
実は reboot というのは再起動するためのコマンドで、入力の中身は関係なしに、再起動してしまいます。本当は再起動する箇所を見つけ出しったかったのに、再起動してしまったのです。
ところで、(1)のコードは冗長な表現であることに気づかれたでしょうか。実は grep コマンドは入力を読み込むファイルを指定することができます。わざわざ cat コマンドを使わなくても、こう書けるのです。
grep reboot *.log …(3)
(1) ではコマンドが2つも起動されますが、(3)ではコマンドが1つだけで済みます。実はコマンドを1つ起動するたびにメモリなどが消費されますので、(3)の表現を使うことにより、メモリも節約できます。たかがコマンド1つと侮ってはいけません。
この grep 病、かなり蔓延しています。この間、こんなコードを見かけました。fooを含むディレクトリを見つけようとして、次のコマンドを実行しているのです。
ls | grep foo …(4)
これはおかしいのではないかと思って手順書を作った人に訊いてみたら、その人は「lsコマンドだけではディレクトリの中身まで見えてしまうではないか」と言い、さらに反論しようとすると「これはレビューが終わった手順書だ。間違いだと思うのなら、あなたがレビューしたらいいのではないか。」と逆切れしてしまいました。いやはや、困りました。ちなみに「fooを含むディレクトリをみつける」のなら、実は次のコマンドだけで事足ります。
ls -ld *foo* …(5)
最近の若い人は UNIX コマンドを断片的にしか知らないようですし、自分でマニュアルを見たりすることもせずに、ただ手順書通りにやればいいと思っているようなのです。確かに手順書の手順から外れることはエラーの元になるのですが、でも明らかに冗長な手順を放置したままにしてよいわけでもありません。作業をするなら、もう少し頭を使うべきではないかと私は思います。