福冨諭の福冨論

RSSリーダーではこちらをどうぞ→https://feeds.feedburner.com/fuktommy

処理の成功・失敗を戻値で返すか例外を使うか

例外をめぐる雑談 - いぬビーム」の件。 IRCだと前提となるコード貼らずに話だけ進めちゃったりするし、 補足とか書くわ。

LLって検査例外ないっぽいから不便

まず本題じゃない方のこっちから。PHPで書いてると

function hoge() throws HogeException
 {
     ...
 }

って書きたくなる。 Java書いてると逆にthrowsとかうざいって思うんだけど。 なんでかというと、関数の呼び出し側でtry-catchを忘れて難儀するとか、 そういうことがあるんだよね。

特別な戻値はやだよね

FileInputStreamみたく

try {
     hoge = new FileInputStream(file);
 } catch (FileNotFoundException e) {
     エラー処理
 }

ってのはよいと思うのね。

hoge = new FileInputStream(file);
 if (hoge == null) {
     エラー処理
 }

はなんか違うと思う。

処理の成功・失敗は?

これは迷う。 Lock (Java Platform SE 6)のイメージで

if (! lock.tryLock()) {
     ロック取れなかったとき
     return;
 }
 ロック取った後の処理

なのか

try {
     lock.tryLock();
 } catch (HogeException e) {
     ロック取れなかったとき
     return;
 }
 ロック取った後の処理

なのか。 例外方式がいいよねという点は次のように考えたときなんだよね。

total = sum(a, b, c, d, e);

は自然なのだけど、

success = lock.tryLock();

は不自然じゃないか、ということ。 これ思いついたときは本当に不自然だと思ったんだけど、 「成功か失敗かを戻値で返す関数」ってたくさんあるから、 あんまり不自然じゃないと思ってきた。

感覚的な話なのだけど、 ファイルを開こうとしたら開けなかったというのはエラーっぽいんだけど、 ロックしようとしたらロックできなかったというのは、エラーじゃない感じがする。 エラーっぽいときだけ例外にしよう、 そういう方針にした方がコードが読みやすいよね、 っていうのを以前どこかで読んだのだけど、出典がみつけられなかった。 たぶん、ちょっと前まではこの方針でよかったのだと思うのね。

でも別の方針として、 数学の関数とか、isHoge(), getHoge() みたいに戻値がありそうなものでない、 tryLock() みたいな戻値のなさそうな字面のものは、 字面の通りに値を戻さなくして、 その代わりに例外を使うというのも、アリといえばありのような気がする。

でも tryLock() で例外ってのは不自然だと思うけどなあ。 true/falseを返すものだという思い込みがあるからかもしんないけど。

Original Article: http://blog.fuktommy.com/1265813506