悪態のプログラマ -28ページ目

悪態のプログラマ

とある職業プログラマの悪態を綴る。
入門書が書かないプログラミングのための知識、会社の研修が教えないシステム開発業界の裏話は、新人プログラマや、これからプログラマを目指す人たちへのメッセージでもある。

「プログラミング中には、作ったプログラムを動かすな。ただソースコードを書いてコンパイルが通ればよい。とにかく、テスト工程に入るまでは絶対に動かさないこと」

あるプロジェクトマネージャが、プログラマにこのような指示をしていた。

おかしなことを言うものだ。

プログラミング中に「動作確認」ができるのなら、積極的に行うべきだろう。そのほうが品質のよいプログラムができるに決まっているからだ。


プログラミングの目的は、単に「ソースコードを書く」ことではない。「正しく動くプログラムを作る」ことである。

文章の誤字・脱字を探すのとは違って、ソースコード上のミス(バグ)は、読み返しただけではなかなか見つからない。実際にプログラムを動かして確認しなければ、見逃してしまうことも多い。経験が少ないプログラマであればなおさらである(※1)。

大きなシステムを作る場合でも、まず一部の機能だけのソースコードを書き、そこだけを動かしてみて、確認すべきだ。その部分が正しく動いたら、別の小さな機能を書く。少し書いては動作を確認し、動作を確認してはまた少し書く。このようにして、小さな機能を着実に作り、それを積み上げていくことで、品質の高いシステムが出来上がるのである(※2)。

プログラマが念入りに「動作確認」を行うほど、品質は高くなる。「プログラミング中にプログラムを動かすな」という指示は、品質を落とすためになされているとしか思えない。

私がそのような指示を受けたプログラマであったら、指示は無視して、プログラミング中の動作確認を行うだろうと思う。また、全てのプログラマにも、そうであって欲しいと思う。


問題は、なぜこのマネージャがバグの数を増やすような指示を出したのか、ということだ。

続く




※1
もちろん、ソースを読み返す必要がない、というわけではないので、誤解のないよう。

※2
テストドリブンとか、テストファーストと呼ばれる手法は、それを徹底(かつ自動化)したものといっていいだろう。



■関連記事
バグを求めるものたち 中編
バグを求めるものたち 後編



図解入門 よくわかる最新ソフトウェアテスト手法の基本と極意―ソフトウェア品質向上のための実践テスト手法
若林 宏
秀和システム (2003/11)
売り上げランキング: 238,824
おすすめ度の平均: 2.25
3 ソフトウェアテストで必要最小限の知識を紹介
2 手始めに読むための本
3 即実践本。この本でなくとも構わないが・・・


世界一わかりやすいプロジェクト・マネジメント
サニー ベーカー G.マイケル キャンベル キム ベーカー
総合法令出版 (2005/04)
売り上げランキング: 7,301
おすすめ度の平均: 5
5 分厚いが読み通す価値あり
5 判り易く・やる気にさせるプロジェクト管理指南書

あるプロジェクトで一緒になったプログラマに、「コーディングってなんですか?」と聞かれたことがある。

この業界で「コーディング」といえば、プログラムのソースコードを書くことである。「プログラミング」と同じような意味と思えばよいだろう(※1)。

彼は何年も経験を積んだプログラマだったし、私達はあまりに日常的に使っている言葉だったので、それが通じなかったことはショックだった。

おそらく、彼がそれまで働いてきた職場では、たまたま「コーディング」という言葉が使われなかったのだろう。


同じ人物には、「CGI ってなんですか?」とも聞かれた。

「CGI」は、一般的には、Web ブラウザから呼び出され、Web サーバ上で動作するプログラムのことである(※2)。

システム開発者業界の人間でなくとも、「ネット」にちょっと詳しい人なら知っているだろう。少なくとも、プログラマなら「常識」の範囲に入る言葉だと思うのだが。。。

とはいえ、同じシステム開発業といっても、Web 系のシステムを全く扱わない「職場」では、「CGI」という言葉が使われる機会がないのも事実である。

おそらく、彼は、プログラミングに関する知識を、自分の「職場」からしか吸収してこなかったのではないだろうか。


コンピュータに興味がないプログラマというのをときどき見かけるが、彼もそういった部類の人物のようであった。コンピュータやプログラミング自体に特に興味がないので、実務に必要な知識しか吸収しないのである。

もちろん、それが悪いというわけではない。自分の職場の中できちんと仕事をこなしていれば、誰にも文句をいわれる筋合いはない。

しかし、プログラマというものは、いつ、別のプロジェクトの応援に回されるか分からない。実際、彼もそうして駆り出されたのである。しかも、そんな時は「即戦力」として期待される。

また、そのようなことがなくとも、この世界の変化は速いのだ。慣れ親しんだ「職場」にも、いつ新しい技術が導入されるかわからない。

そんな時、実務から得られた知識だけでは、即座に対応できないだろう。井の中の蛙とならず、少しは「大海」の情報を集めておくことも必要なのではないかと思うのだが。




※1 コーディングとプログラミング
実際には微妙にニュアンスが違う→ e-Words

※2 CGI (Common Gateway Interface)
厳密には、プログラムを呼び出すための仕組み(インターフェース)のことだが、日常的にはプログラム自体を指す場合のほうが多い → e-Words



■関連記事
プログラマとして歓迎したい人とは
コンピュータの普及はプログラマを育てるか?



アルゴリズムの絵本-プログラミングが好きになる9つの扉
(株)アンク
翔泳社 (2003/08/05)
売り上げランキング: 49,095
おすすめ度の平均: 4
4 アルゴリズムとは・・・
4 入門書には向いてる
4 図解は馴染みやすいがC言語の基礎は必須


Javaプログラマのためのもっとプログラミングが好きになる本
橋本 正徳 吉原 日出彦
秀和システム (2004/12)
売り上げランキング: 660,821

その1 」で書いたように、例外は非常事態が発生した時の「警報」として考えるべきである。

しかし、通常の処理の流れの中で例外を使ってしまう人もいる。

職場の火災報知器に例えれば、「俺が火災報知器を鳴らすから、それを合図に会議を始めよう」と言っているようなものである。


端的な例では、こんなケースである。

1: try{
2:   for( ... ){
3:     // 何らかの処理
4:     ...
5:     for( ... ){
6:       // 何らかの処理
7:       ...
8:       if( ループを抜けたい ){
9:         // 例外を投げる
10:         throw new Exception();
11:       }
12:     }
13:   }
14: }catch(Exception e){
15:   // ループを抜けた
16 }

これは、いうまでもなく例外の誤用である。「ループを抜けたい」というような不純な動機で例外を投げてはいけない(※)。

また、こんな例もある。

1: /** 文字列が数値を表すかどうかを調べる関数 */
2: boolean isNumeric(String str){
3:  try{
4:    // 整数に変換
5:    Integer.parseInt(str);
6:  }catch(NumberFormatException e){
7:    // 変換に失敗した
8:    return false;
9:  }
10:  return true;
11:}

5行目の Integer.parseInt() は、文字列を数値に変換する関数である。変換に失敗すると NumberFormatException という例外を発生させる。

ここでは、文字列 str が数値を表しているかどうかをチェックするためだけに Integer.parseInt() を呼び出し、「NumberFormatException が発生したら数値を表す文字列ではない」という判断をしている(6~8行目)。

このようなことは、ついやってしまいがちなのだが、例外を「警報」として考えるならば、やはり誤用ということになるだろう。


日常的に鳴っているような火災報知器は警報機としての意味をなさない。狼が来たと毎日のように叫んでいる少年と同じである。

通常処理で頻繁に例外を使っていると、本当に非常事態が発生したときに、それを無視してしまうようなプログラムになりやすい。また、一見して、通常処理が書いてあるのか、例外処理が書いてあるのか分からないような、読みにくいソースコードにもなってしまうだろう。

狼が来たと叫ぶのは、本当に狼が来たときにだけにしておきたいものである。



※もちろん、ループの中でエラーが発生したために例外を発生させ、結果的にループを抜けるようなケースは問題ない。



■関連記事
例外論 ~その1~ 警報



デザインパターンとともに学ぶオブジェクト指向のこころ
アラン・シャロウェイ ジェームズ・R・トロット 村上 雅章
ピアソン・エデュケーション (2005/09/16)
おすすめ度の平均: 5
5 ★デザインパターンとともに学ぶオブジェクト指向のこころ
5 タイトルに偽り無し
5 デザインパターンとともに学ぶオブジェクト指向のこころ


プログラミング言語Java
プログラミング言語Java
posted with amazlet on 06.05.06
ケン アーノルド デビッド ホームズ ジェームズ ゴスリン
ピアソンエデュケーション (2001/06)
売り上げランキング: 76,888
おすすめ度の平均: 4.14
1 読了不可能と思います
5 中級者へのステップに最適
5 レベルアップ前の基礎固めとして最適な一冊

近頃のプログラミング言語では、プログラムの実行中に何か異常事態が発生したら、警報が発せられるようになっている。この警報を「例外」などという(※1)。

プログラムを書くときは、例外が発生したらどうするのか、ということを決める(設計する)必要がある。一般的には、例外を検出したら、通常の処理を中断し、緊急用の処理、すなわち「例外処理」を実行する(※2)。

職場で火災報知器が鳴れば、仕事の途中であっても中断して、緊急避難すると思うが、それと同じことだと思ってほしい。

一言で「例外処理」といってもいろいろある。例えば、どんな異常が起こったかをログに記録したり、ユーザーにメッセージで知らせる。あるいは、データなどを壊さないように、途中まで行っていた処理をキャンセル(ロールバック)したり、プログラムを強制終了したりすることもあるだろう。


プログラマは、どのようにして例外を検出(catch)するのか、あるいはどうやって例外を発生(throw)させるのかといった「仕組み」を覚えただけでは、例外というものを本当に理解したとはいえない。

例外は異常事態を知らせる「警報」として理解することが重要である。何か「異常なこと」、「普通じゃない」ことが起こっているからこそ「例外」なのである(※3)。


しかし、ソースコードを読んでいると、そのあたりのことが分かっていないプログラマもいるようだ。例外を検出しても、無視して通常処理を続けてしまうようなコードを見かけることがあるのだ(※4)。

「例外を無視する」ということは、火災報知器が鳴り出しても、耳を塞ぎ、何事も無かったかのように仕事を続けているのと同じことである。

あるいは、自分の火の不始末(プログラミング上の不備)を隠すために、火災報知器のスイッチを切って知らん顔しているといってもいいだろう。

そのようなプログラムでは、異常事態の発生が見逃され易くなり、不具合の発見が遅れてしまう。酷いときには大火災になってしまうかもしれない。

例外を扱うという時には、よく考えてほしいのである。




※1
ここでは「発生する」と書いているが、プログラマが自分で例外を発生させるコードを書くこともできる。「異常事態」の例としては、ファイルの読み書きに関するエラー、メモリ不足、Null ポインタへのアクセス、ゼロによる割算などがある。

※2
C++ や Java などでは、「try」というキーワードに続くブロック(通常処理)の中で異常が発生すると、「catch」というキーワードに続くブロック(例外処理)が実行される。また、旧来の VB (Visual Basic) でも、「On Error ...」といった構文で同様のことができる。

※3
実際のプログラミングでは、「警告 Warning」と「エラー Error」のように、「異常さ」のレベルを分けて扱うことが多いが、ここでは、レベルは考えず、まとめて「警報」と呼んでいる。

また、「例外」という言葉も広義に使っている。例えば、Java の「例外 Exception」クラスは「エラー Error」クラスと区別されるが、本文中の「例外」は、その両方を含んでいるものと考えてもらいたい(Java でいえば Throwable 実装クラス一般)。

※4
むしろ、例外を無視するためにわざと catch するといった方がいいかもしれない。例えば、こんな感じの Java ソースがあった。

1: for(int i=0; i<n; i++){
2:  MyClass m = myObjects.getMyObject(i);
3:   try{
4:    m.do();
5:   }catch(NullPointerException e){
6:    // なにもしない
7:  }
8: }

実行すると、一見、正常に処理は動くようだが、実は4行目で大量に NullPointerException が発生していた。確信犯である。

あるいは、"On Error Resume Next" という行を外すと動かなくなる VB プログラムもあった。"On Error Resume Next" は、エラー(例外)が発生しても無視して、次の行を実行するというものである。



■関連記事
例外論 ~その2~ 狼が来た



Java謎+落とし穴徹底解明
Java謎+落とし穴徹底解明
posted with amazlet on 06.05.06
前橋 和弥
技術評論社 (2001/12)
売り上げランキング: 59,878
おすすめ度の平均: 4
4 ”Java言語を知る”ことができる本
4 この著者はJavaの仕様をよく調べている
4 Javaの参考書というよりは...


C++プログラミング〈Vol.2〉
ハーベイ・M. ダイテル ポール・J. ダイテル Harvey M. Deitel Paul J. Deitel 小嶋 隆一
ピアソンエデュケーション (1999/06)
売り上げランキング: 224,016
おすすめ度の平均: 4.5
5 C++コンパイラのチュートリアルを終えたら、最初に手にとるべき本。
4 C++に関する詳しい解説書

「グローバル変数」は多くのプログラマに嫌われている。

もし、あなたがプログラマで、その理由が分からないとしたら、一度よく考えてみてほしい。「とりあえず、グローバル変数を使わなければいいのだろう」などと安易に構えていては、どこかで過ちを起こすかもしれない。


例えば、Java には「グローバル変数」というものはないが、安心はできない。

クラスのメンバ変数(フィールド)においても、private にすべきものを public や protected にすれば、同じ「理由」によって嫌われることだろう。むしろ、オブジェクト指向の基本である「カプセル化」の意味が分かっていないという点で、グローバル変数の乱用よりもタチが悪いといってもいい。

また、ローカル変数(関数内の変数)で事足りるものをメンバ変数にしたり、メンバ関数(メソッド)の引数や戻り値にすべきものをメンバ変数にするのも、同じことである。

つまり、「グローバル変数」自体ではなく、「変数の使い方」が問題なのだ。たとえ、言語仕様からグローバル変数というものが排除されたとしても、同じような乱用はどこかに残り続けるだろう。

グローバル変数が嫌われる「理由」を理解せよ、という所以である。


ここでの「乱用」とは、変数にアクセス(参照や更新)ができる範囲(スコープ)を必要以上に広げてしまうことである。

スコープが広い変数、つまり、どこからでもアクセスできる変数というのは、ソースコードの書き手にとっては便利なものかもしれない。しかし、読み手にとっては、非常に厄介なものだ。その変数がどこで何に使われているのか、広範囲にチェックしなくてはならなくなるからだ。

結果的に、そのようなコードの作者は、「自分が楽に書ければそれでよい」というような自分勝手な人間と評価されるかもしれない。そうでないとしても、変数のスコープの設定(設計)をしない怠惰な者とされるだろう。




※参考(e-Words)
グローバル変数
ローカル変数
クラス
カプセル化



■関連記事
誰のためのコード?
まずは丁寧なプログラミングを



職業プログラマー入門―システム開発者を目指すあなたへ設計からC言語コーディング、テストまで
遠矢 行史 矢沢 路朗 川人 弘毅 鶴巻 浩史 レッドフォックス
エーアイ出版 (2003/03)
売り上げランキング: 125,680
おすすめ度の平均: 4.2
4 紅狐魂!
5 わかりやすい
2 (null)


やさしいJava 第3版
やさしいJava 第3版
posted with amazlet on 06.05.06
高橋 麻奈
ソフトバンククリエイティブ (2005/09/01)
売り上げランキング: 10,005
おすすめ度の平均: 4
5 JAVA言語の文法を一から学んで行こうとする方にオススメ
3 入門用