2010年4月20日火曜日

関数と戻り値と例外

値を返さなくても、「関数」とはこれ如何に?

ソフトウエアでいう「関数」は値を返さない事もあります。

関数が「値を返す」と言っても、その関数を呼んだ側が、変数に入れなければ、返さないのと同義ではあります。ただし、関数の実装としては、返すのと返さないのとはおお違いです。

perlでは、関数の最後の「式」を返します。なんか過激な実装ですが、何かしら値は戻るでしょう。

pythonとPHPは、return文の式の値が戻ります。しかし、returnを書かなくてもインタプリタは怒りません。更に、関数を呼んだ側でもエラーにはなりません。

変数の中身には?null/Noneが入っています。

これは、ハマる場合がままあります。

実装者の趣味次第だとは思いますが、
  1. 配列を渡して
  2. 何らかの処理をさせて
  3. 出来上がった配列を返す
そういう関数を想定してください。しかし、例によって、プログラマは間違えますので、
変なデータ(上の場合には、空の配列とか)をもらった場合には、何かしら「変でしたよ」って言わなきゃなりません。

変だったなりに処理を続けるか、エラーにするかは悩みどころです。

エラーの場合にはnullを返す。のは割とよく考えると思います。あれ筆者だけ?しかし、returnを忘れてもnullが帰ります。


  • エラーだったのか?
  • return忘れだったのか?


デバッグが面倒臭いことになります。

そこで例外の出番です。

「例外処理」を何故「エラー処理」と命名してないかというと、「エラー」とは限らないからです。より上位の処理で、回復できる&代替できる可能性があるからです。ユーザには、「エラー」と言わないケースもあります。

例えば、営業職の人が、顧客に怒られた。しかし、上司が出張ってくれば、オトナの解決法があるかもしれません。これが例外処理です。

顧客からクレーム系は、まあエラーと言っちゃってもいいかも知れませんが、不可抗力やら外的要因やら、色々あります。

当事者の手に余る自体は、「例外」です。上司に連絡しましょう。

入力間違いなんかは、本来は、「処理関数」に入れるまえに処理すべきでしょう。そういう意味では「処理関数」の手には余ります。「処理関数」の立場では、「エラーだ」とも言えません。

Javaは、例外を馬鹿正直に実装した言語の代表と言えましょう。

関数宣言で、自分が出す予定の例外を列挙しなきゃなりません。さもないと、関数内部で、thrawさせてもらえない。しかも、呼び出す方では、必ずcatchしなければならない。

悪い手ではありませんが、面倒臭くなりがちなので、とにかくcatchを書くけど、何もしない、みたいな形骸化する可能性はあります。面倒臭いからnullを返しちまえ。とか。

とは言え、例外補足を要求しない言語だと、そのまま例外が画面表示まで貫通しちゃって、ようやく思い出すので、どっちもどっち。

って言うかね。
appengine pythonだと、return忘れとか、
例外が画面まで出ちゃったりとか。

とりあえず次回は忘れないようにエントリを書いている次第です。