![]() ![]() |
契約があるときはいつも、リスクは、誰かが契約を破るであろうという点にあります。これは、例外<exception>が発生するところです。
例外 -- 契約違反<contract violation> -- は、いくつかの原因から上がることがあります。一つは、もし表明が監視されているならば、表明の違反です。もう一つは、算術演算の桁あふれや新たなオブジェクトを生成するための記憶域の不足といった、異常な状況を指示するためにハードウェアやオペレイティング システムによって誘発される合図<signal>の発生です。
ルーチンは、例外処理に固有な仕様を設けている限り、もし例外がその実行中に上がるならば、失敗するでしょう。ルーチンの失敗は、例外の三番目の原因です。つまり、失敗がその呼出し元において例外を誘発するルーチンです。
しかしながら、ルーチンは、rescue 句を通じて例外を処理します。このオプショナルな句は、現在のオブジェクトを??stableな状態(クラスの不変条件を満足するもの)へ導くことによって、"ものごとをつぎあて<patch>"しようと企てます。それから、次の二つのいずれかの方法で打ち切ることができます。
rescue
句では、通常他の戦略を通じて、その契約をもう一度満たすことを意図して、ルーチンにその実行を最初から再開始させる、retry
命令を実行することもできます。このことは、retry
句の前にある rescue 句の命令が例外の原因を正すことを意図している、ということを仮定しています。
もし rescue
句が retry 句で終わらないならば,ルーチンは失敗します。つまり、直ちに例外を合図して、その呼出し元へ返ります(呼出し元の
rescue 句が、同一の規則に従って実行されるでしょう)。
原則は、ルーチンが成功するか失敗するかのいずれかでなければならない、つまり、その契約を満たすか否か、ということです。後者の場合には、その呼出し元に例外を誘発することによって通知しなければなりません。
通常は、システムのいくつかのルーチンだけが明示的な rescue 句を含むことになります。rescue 句の無いルーチンの実行中に発生する例外は、何もしない、事前定義の rescue 手続きを誘発することになるので、ルーチンの呼出し元へ例外を伝播して、そのルーチンを直ちに失敗させることになります。
例外機構を使用する例は、メッセージを電話回線上へ転送しようとするルーチン attempt_transmission です。実際の転送は、外部にある低水準のルーチン transmit によって遂行されます。しかしながら、ひとたび転送が始まって、もし回線が切断されたならば、transmit は、例外を誘発して、突然に失敗することになります。ルーチン attempt_transmission は、最大でも50回転送を試み、呼出し元へ返る前に、真理値の属性 successful に、結果に依存する true または false を設定します。そのルーチンのテキストは次にあります。
初期化規則は、局所的な実体である failures が入り口でゼロへ設定されることを保証しています。
この例は、例外機構の単純さを示しています。rescue 句は、けっしてルーチンの元々の意図を達成しようとは試みません。このことは、本体(do句)の単独責任です。rescue 句の役割は、関与したオブジェクトを掃除することと、それから失敗するか再試行するかのいずれかです。
この洗練された例外機構は、予期せぬ事象に対する保護を必要とするが、この保護に対して支払う安全性と単純性の犠牲を予期できないソフトウェア開発者にとって本質的です。
![]()
URL
for this page: http://www.eiffel.com/doc/manuals/language/intro/exceptions.maker.html.
Copyright 1994-1998 Interactive Software Engineering Inc. All rights reserved.