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の提供に 要求される関数定義はありません。