Macro HANDLER-BIND
handler-bind
({
binding}
*) form* => result*
binding::= (type handler)
type - 型指定子
handler - フォーム。評価されたらhandler-functionを生成します。
handler-function - ひとつの引数を取る関数指定子
form - 暗黙のprogn
result - formによる返却値
handlerが束縛されている効果がある 動的環境の下でformを評価します。
各handlerは評価されてhandler-functionにならなければならず、 formを評価している間は、 指定されたtypeのコンディションが捕捉されたときに その関数が使用されます この関数はひとつの引数を受け取れなければならず、 その引数には通知されたコンディションが渡されます。
もし複数のhandlerの束縛が指定されたとき、 handlerの束縛は、順番に上から下へ (視覚的にtypecase
に似た方法で) マッチするものを探します。 もし適切な型が見つかったときは、 その関連するハンドラーは、 これらのhandlerの束縛が見えないような動的環境下で (再帰的なエラーを回避するため)実行されます。 もしhandlerが下がると、他に続くhandlerを探します。
もし適切なhandlerが無かったときは、 動的に囲まれた部分から他のハンドラを探します。 もし外側にもhandlerがなかったときは、 signal
は戻るか、あるいはerror
はデバッガーに入ります。
下記のコードは、もしボディ部でunbound
な変数のエラーが通知されたら (そしてハンドラーの介入が無かったら)、 最初の関数が呼ばれます。
handler-bind ((unbound-variable #'(lambda ...))
(error #'(lambda ...)))
( ...)
もしそれ以外の何らかのエラーが通知されたら、 二番目の関数が呼び出されます。 いずれの場合も、関連する関数のコードを実行している間委は、 どちらのハンドラーもアクティブになりません。
defun trap-error-handler (condition)
(format *error-output* "~&~A~&" condition)
(throw 'trap-errors nil))
(
defmacro trap-errors (&rest forms)
(catch 'trap-errors
`(handler-bind ((error #'trap-error-handler))
(
,@forms)))
list (trap-errors (signal "Foo.") 1)
(error "Bar.") 2)
(trap-errors (+ 1 2))
(
>> Bar.=> (1 NIL 3)
"FOO"
は印刷されませんが、 これはsignal
によってsimple-condition
を通知したためであり、 型error
ではないため、 trap-errors
によって用意されたerror
のハンドラーが トリガーされないのです。
なし。
なし。
なし。
なし。