Variable *DEBUGGER-HOOK*
2つの引数(コンディションと、 デバッガーに入った時点での*debugger-hook*
の値) の関数指定子か、nil
。
*debugger-hook*
の値がnil
ではない場合、 invoke-debugger
の呼び出しによるものか、 あるいは捕捉されないコンディションを error
かcerror
で呼び出して 自動的にデバッガーに入ろうとしたとき、 この変数の値のものが通常の方法でデバッガーに入る前に呼び出されます。 この関数は、コンディションを捕捉するか(遷移制御)、 あるいは普通に終了するか(標準デバッガーが実行される)の どちらかになります。 デバッグ中に再帰エラーを抑えるため、 その関数が呼ばれる前にinvoke-debugger
によって *debugger-hook*
がnil
に束縛されます。
defun one-of (choices &optional (prompt "Choice"))
(let ((n (length choices)) (i))
(do ((c choices (cdr c)) (i 1 (+ i 1)))
(null c))
((format t "~&[~D] ~A~%" i (car c)))
(do () ((typep i `(integer 1 ,n)))
(format t "~&~A: " prompt)
(setq i (read))
(fresh-line))
(nth (- i 1) choices)))
(
defun my-debugger (condition me-or-my-encapsulation)
(format t "~&Fooey: ~A" condition)
(let ((restart (one-of (compute-restarts))))
(if (not restart) (error "My debugger got an error."))
(let ((*debugger-hook* me-or-my-encapsulation))
(invoke-restart-interactively restart))))
(
let ((*debugger-hook* #'my-debugger))
(+ 3 'a))
(+, A, is not a number.
>> Fooey: The argument to 1] Supply a replacement for A.
>> [2] Return to Cloe Toplevel.
>> [1
>> Choice: and use: (+ 5 'b)
>> Form to evaluate +, B, is not a number.
>> Fooey: The argument to 1] Supply a replacement for B.
>> [2] Supply a replacement for A.
>> [3] Return to Cloe Toplevel.
>> [1
>> Choice: and use: 1
>> Form to evaluate => 9
なし。
ユーザーが対話形式で打ち込んだコードを評価するとき、 フック関数がその第2引数である関数に *debugger-hook*
を束縛すると、 同じ対話的機能を使用して再帰的エラーを処理することができるので 便利なことがあります。