Function CERROR
cerror
continue-format-control datum &rest
arguments => nil
continue-format-control - format-control
datum, arguments - コンディション指定子であり、標準の型はsimple-error
。
cerror
は、datumによって指定されたコンディションを 効果的にerror
で実行します。
どこかの関数で暗黙的にerror
が呼ばれたとき、 もしそのコンディションが捕捉されなかったときは、 (invoke-debugger condition)
が実行されます。 シグナルが通知され、 そしてデバッガーに到達したとき、 continue
restart
を使うことで コードの実行を継続することができます (例えばcerror
から戻ります)。
もしdatumがコンディションならargumentsを指定できますが、 それはcontinue-format-controlとの組み合わせでのみ使用されます。
defun real-sqrt (n)
(when (minusp n)
(setq n (- n))
(cerror "Return sqrt(~D) instead." "Tried to take sqrt(-~D)." n))
(sqrt n))
(
4)
(real-sqrt => 2.0
9)
(real-sqrt -error in REAL-SQRT: Tried to take sqrt(-9).
>> Correctable
>> Restart options:1: Return sqrt(9) instead.
>> 2: Top level.
>> 1
>> Debug> :continue => 3.0
define-condition not-a-number (error)
(
((argument :reader not-a-number-argument :initarg :argument))lambda (condition stream)
(:report (format stream "~S is not a number."
(condition)))))
(not-a-number-argument
defun assure-number (n)
(loop (when (numberp n) (return n))
(cerror "Enter a number."
(
'not-a-number :argument n)format t "~&Type a number: ")
(setq n (read))
(fresh-line)))
(
(assure-number 'a)error in ASSURE-NUMBER: A is not a number.
>> Correctable
>> Restart options:1: Enter a number.
>> 2: Top level.
>> 1
>> Debug> :continue 1/2
>> Type a number: => 1/2
defun assure-large-number (n)
(loop (when (and (numberp n) (> n 73)) (return n))
(cerror "Enter a number~:[~; a bit larger than ~D~]."
("~*~A is not a large number."
numberp n) n)
(format t "~&Type a large number: ")
(setq n (read))
(fresh-line)))
(
10000)
(assure-large-number => 10000
(assure-large-number 'a)error in ASSURE-LARGE-NUMBER: A is not a large number.
>> Correctable
>> Restart options:1: Enter a number.
>> 2: Top level.
>> 1
>> Debug> :continue 88
>> Type a large number: => 88
37)
(assure-large-number error in ASSURE-LARGE-NUMBER: 37 is not a large number.
>> Correctable
>> Restart options:1: Enter a number a bit larger than 37.
>> 2: Top level.
>> 1
>> Debug> :continue 259
>> Type a large number: => 259
define-condition not-a-large-number (error)
(
((argument :reader not-a-large-number-argument :initarg :argument))lambda (condition stream)
(:report (format stream "~S is not a large number."
(condition)))))
(not-a-large-number-argument
defun assure-large-number (n)
(loop (when (and (numberp n) (> n 73)) (return n))
(cerror "Enter a number~3*~:[~; a bit larger than ~*~D~]."
(
'not-a-large-number
:argument n numberp n)
:ignore (
:ignore nt)
:allow-other-keys format t "~&Type a large number: ")
(setq n (read))
(fresh-line)))
(
(assure-large-number 'a)error in ASSURE-LARGE-NUMBER: A is not a large number.
>> Correctable
>> Restart options:1: Enter a number.
>> 2: Top level.
>> 1
>> Debug> :continue 88
>> Type a large number: => 88
37)
(assure-large-number error in ASSURE-LARGE-NUMBER: A is not a large number.
>> Correctable
>> Restart options:1: Enter a number a bit larger than 37.
>> 2: Top level.
>> 1
>> Debug> :continue 259
>> Type a large number: => 259
存在するハンドラーの束縛
なし。
error
, format
, handler-bind
, *break-on-signals*
, simple-type-error
もしdatumが文字列ではなくコンディションの型のときは、 format
の命令である~*
がcontinue-format-control内で 初期化引数リストのキーワードを無視するためには特に有効です。 例えば下記の通り。
cerror "enter a new value to replace ~*~s"
(
'not-a-number :argument a)