Function ABORT, CONTINUE, MUFFLE-WARNING, STORE-VALUE, USE-VALUE

UP


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-valuenilを返却し、 abortmuffle-warningは 型control-errorのエラーを発生します。

もしconditionnilではないときは、 それらのrestartは、明にconditionと関連付けられているものか、 あるいはどのコンディションにも関連付けられてないものかの どちらかのみが集められます。 これは、排他されたrestartというのは、 関連付けられたコンディションの集合が空ではなく、 その要素に指定したconditionが含まれていないということです。 もしconditionnilのときは、 全ての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の提供に 要求される関数定義はありません。


TOP, Github