I would like to have the `:interactive' part (and maybe
also the body) of a restart access the condition that
triggerd it, much in the same way as the condition
is available for the `:test' function.
I want this because I want the user to choose
a value from a list that is composed in the
lexical environment where the error is signaled.
I feel I'm trying to use `restart-case' in a
way it is not meant for; I guess that since what I
want to achieve is so common there is an elegant solution.
The problem occurs in the `:interactive' part of the
restart-case call:
(define-condition value-error (error)
(choice-list))
(define-condition no-values (value-error)
(:report (lambda (condition stream)
(format stream "No value computed."))))
(define-condition ambigious (value-error)
(:report (lambda (condition stream)
(format stream "Ambigious values computed: ~A"
(slot-value condition 'choice-list)))))
(defun set-a-value ()
(let ((some-lexical-var (form))
(values (compute-values)))
(cond
((rest values)
(error 'ambigious :choice-list values))
((null values)
(error 'no-values :choice-list (get-alternatives some-lexical-var)))
(T (setf (a-place) (first values))))))
(restart-case (set-a-value)
(choose-value (new-value)
:report "Choose a value."
:test (lambda (condition)
(typep condition 'value-error)
:interactive
(lambda ()
(let (;;
;; ***Here I want to get the list out of the condition:***
;;
(choice-list (slot-value CONDITION 'choice-list))
(index 0))
(dolist (val choice-list)
(format *query-io* "~&~D ~A~%" (incf index) val))
(nth (progn (format *query-io* "~&Table nr: ")
(read))
choice-list)))
(setf (a-place) new-value))))
I could ofcourse use a dynamic variable, or put the whole restart-case
in the lexical context where the choice-list is known, but this seems
not the right way to me.
I would be happy if anyone could explain how I should achieve
the desired effect, or maybe could point me to a good example
of the use of the condition system.