MORE我儘は実装側の罪、エラー処理2016.02.14こんにちは、プログラマーの安藤ですさて、前回は契約プログラミングのほんのさわりについて書きました。契約プログラミングは非常に強力な概念ですが、その成り立ちもあって残念なことにかなり理屈っぽい。今回はそれに関連してエラー処理の話を理屈っぽく進めます。ところで、一口にエラーといっても概念が大雑把すぎて理屈が進まない。失敗:手続きが事後条件を満たさずに処理を終えること正常終了:手続きが処理を最後まで実行して終えること異常終了:手続きが処理を中断して呼び出し側に制御を戻すことでは、二人の登場人物に出てきてもらいましょう、「手続きの呼び出し側」と「手続きの実装側」です。2者の間では事前に約束事が決められています。甲と乙の間の契約です。呼び出し側は手続きの事前条件を満たした上で手続きを呼び出します。事前条件を満たせない場合は、手続き側に正しい結果を要求する権利はありません。手続き側は事前条件が満たされているものとして仕事を進めます。仕事をやり遂げたあかつきには事後条件を満たした状態となり、これをもって呼び出し側の要求に応えたものとします。はい、そこの理屈っぽいアナタ、こんな疑問が湧いてきませんか?“仕事をやり遂げたあかつきには”だって?中途で仕事を放り出すことがあるのか?それは実装側のバグじゃないのか?残念なこと手続きが異常終了することはあるのです。実装側のバグだとも言い切れないのです。ここでさらにもう一人の登場人物に出てきてもらいましょう。「手続きの外部サービス」さんです。デバイスにアクセスしたりします。これらをひっくるめて「外部サービス」と呼んじゃいましょう。「手続き実装が呼び出すさらに別の手続き」じゃあ、ややこしくて話が進められない。外部サービスが失敗することはあります。呼び出し側に落ち度が無いにもかかわらず。「よし、ユーザーが指定したセーブ先のファイルが書き込みOPENできた、デバイスの残り容量も充分だ。WRITE」ところが書き込み先のリムーバルストレージが引っこ抜かれたりするのです。いうわけで、どんなに正しくてバグのない処理でも失敗するときは失敗します。正しい処理をしたからこそ失敗するわけです。サービスを利用する側は、それが失敗したかどうかを判定することはできるでしょうか?利用者に落ち度がないのにサービスが提供できなかった場合、失敗したことを利用者に伝える必要があります。サービスが失敗した結果は、成功した結果とは区別できなければなりません。この、正常時とは区別できる結果のことを、「いかなる正常なケースとも異なる」という意味で例外と呼びます。今、私は理屈について話をしているのであって、特定の言語の機能についての話ではないってことをお忘れなく。例外を呼び出し側に伝える方法はいろいろあります。どのような正常な値とも異なる値を返す。処理結果と一緒に終了コードを返す。