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)
(trap-errors (error "Bar.") 2)
(+ 1 2))
>> Bar.
=> (1 NIL 3)"FOO"は印刷されませんが、 これはsignalによってsimple-conditionを通知したためであり、 型errorではないため、 trap-errorsによって用意されたerrorのハンドラーが トリガーされないのです。
なし。
なし。
なし。
なし。