% Function ABORT, CONTINUE, MUFFLE-WARNING, STORE-VALUE, USE-VALUE
Function ABORT
, CONTINUE
, MUFFLE-WARNING
, STORE-VALUE
, USE-VALUE
abort
&optional
condition => |
continue
&optional
condition => nil
muffle-warning
&optional
condition => |
store-value
value &optional
condition => nil
use-value
value &optional
condition => nil
value - オブジェクト
condition - コンディションオブジェクトか、nil
もっとも最近確立された適用可能なrestart
のうち、
関数と同じ名前を持つものへ制御が遷移されます。
つまり、abort
関数は
適用可能なabort
restart
を探し、
continue
関数は
適用可能なcontinue
restart
を探し、
他も同様です。
もしそのようなrestart
が存在しないときは、
continue
, store-value
,
use-value
はnil
を返却し、
abort
とmuffle-warning
は
型control-error
のエラーを発生します。
もしconditionがnil
ではないときは、
それらのrestart
は、明にconditionと関連付けられているものか、
あるいはどのコンディションにも関連付けられてないものかの
どちらかのみが集められます。
これは、排他されたrestart
というのは、
関連付けられたコンディションの集合が空ではなく、
その要素に指定したconditionが含まれていないということです。
もしconditionがnil
のときは、
全てのrestart
が集められます。
;;; ABORT restartの例
(defmacro abort-on-error (&body forms)
`(handler-bind ((error #'abort))
,@forms)) => ABORT-ON-ERROR
(abort-on-error (+ 3 5)) => 8
(abort-on-error (error "You lose."))
>> Returned to Lisp Top Level.
;;; CONTINUE restartの例
(defun real-sqrt (n)
(when (minusp n)
(setq n (- n))
(cerror "Return sqrt(~D) instead." "Tried to take sqrt(-~D)." n))
(sqrt n))
(real-sqrt 4) => 2
(real-sqrt -9)
>> Error: Tried to take sqrt(-9).
>> To continue, type :CONTINUE followed by an option number:
>> 1: Return sqrt(9) instead.
>> 2: Return to Lisp Toplevel.
>> Debug> (continue)
>> Return sqrt(9) instead.
=> 3
(handler-bind ((error #'(lambda (c) (continue))))
(real-sqrt -9)) => 3
;;; MUFFLE-WARNING restartの例
(defun count-down (x)
(do ((counter x (1- counter)))
((= counter 0) 'done)
(when (= counter 1)
(warn "Almost done"))
(format t "~&~D~%" counter)))
=> COUNT-DOWN
(count-down 3)
>> 3
>> 2
>> Warning: Almost done
>> 1
=> DONE
(defun ignore-warnings-while-counting (x)
(handler-bind ((warning #'ignore-warning))
(count-down x)))
=> IGNORE-WARNINGS-WHILE-COUNTING
(defun ignore-warning (condition)
(declare (ignore condition))
(muffle-warning))
=> IGNORE-WARNING
(ignore-warnings-while-counting 3)
>> 3
>> 2
>> 1
=> DONE
;;; STORE-VALUE restartとUSE-VALUE restartの例
(defun careful-symbol-value (symbol)
(check-type symbol symbol)
(restart-case (if (boundp symbol)
(return-from careful-symbol-value
(symbol-value symbol))
(error 'unbound-variable
:name symbol))
(use-value (value)
:report "Specify a value to use this time."
value)
(store-value (value)
:report "Specify a value to store and use in the future."
(setf (symbol-value symbol) value))))
(setq a 1234) => 1234
(careful-symbol-value 'a) => 1234
(makunbound 'a) => A
(careful-symbol-value 'a)
>> Error: A is not bound.
>> To continue, type :CONTINUE followed by an option number.
>> 1: Specify a value to use this time.
>> 2: Specify a value to store and use in the future.
>> 3: Return to Lisp Toplevel.
>> Debug> (use-value 12)
=> 12
(careful-symbol-value 'a)
>> Error: A is not bound.
>> To continue, type :CONTINUE followed by an option number.
>> 1: Specify a value to use this time.
>> 2: Specify a value to store and use in the future.
>> 3: Return to Lisp Toplevel.
>> Debug> (store-value 24)
=> 24
(careful-symbol-value 'a)
=> 24
;;; USE-VALUE restartの例
(defun add-symbols-with-default (default &rest symbols)
(handler-bind ((sys:unbound-symbol
#'(lambda (c)
(declare (ignore c))
(use-value default))))
(apply #'+ (mapcar #'careful-symbol-value symbols))))
=> ADD-SYMBOLS-WITH-DEFAULT
(setq x 1 y 2) => 2
(add-symbols-with-default 3 'x 'y 'z) => 6
適用可能なrestart
が使用可能なときに
制御の遷移が起こるかもしれませんし、
あるいは(abort
関数か
muffle-warning
関数の場合は)
実行が停止するかもしれません。
もし適用可能なabort
restart
が
利用不可の状態でabort
関数が実行されれたときか、
適用可能なmuffle-warning
restart
が
利用不可の状態でmuffle-warning
関数が実行されれたときは、
型control-error
のエラーが発生します。
invoke-restart
,
9.1.4.2. restart
,
9.1.4.2.2. restart
のインターフェイス,
assert
,
ccase
,
cerror
,
check-type
,
ctypecase
,
use-value
,
warn
(abort condition) == (invoke-restart 'abort)
(muffle-warning) == (invoke-restart 'muffle-warning)
(continue) == (let ((r (find-restart 'continue))) (if r (invoke-restart r)))
(use-value x) == (let ((r (find-restart 'use-value))) (if r (invoke-restart r x)))
(store-value x) == (let ((r (find-restart 'store-value))) (if r (invoke-restart r x)))
この仕様書でuse-value
restart
の提供に
要求される関数定義はありません。