Macro HANDLER-BIND

UP


Macro HANDLER-BIND

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のハンドラーが トリガーされないのです。

副作用

なし。

影響

なし。

例外

なし。

参考

handler-case

備考

なし。


TOP, Github