% Variable *DEBUGGER-HOOK*
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))
>> Fooey: The argument to +, A, is not a number.
>> [1] Supply a replacement for A.
>> [2] Return to Cloe Toplevel.
>> Choice: 1
>> Form to evaluate and use: (+ 5 'b)
>> Fooey: The argument to +, B, is not a number.
>> [1] Supply a replacement for B.
>> [2] Supply a replacement for A.
>> [3] Return to Cloe Toplevel.
>> Choice: 1
>> Form to evaluate and use: 1
=> 9
なし。
ユーザーが対話形式で打ち込んだコードを評価するとき、
フック関数がその第2引数である関数に
*debugger-hook*
を束縛すると、
同じ対話的機能を使用して再帰的エラーを処理することができるので
便利なことがあります。