You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
(defun expand-handler-bind (type lambda-list &key before-unwind after-unwind)
"Helper for the HANDLER-CASE* macro. This one creates the HANDLER-BIND lambdas out of the :BEFORE-UNWIND form."
(declare (ignorable after-unwind))
(when before-unwind
(when (null lambda-list)
(error ":BEFORE-UNWIND must bind the condtion to a variable."))
`(,type (lambda ,lambda-list (declare (ignorable ,@lambda-list)) ,before-unwind))))
(defun expand-handler-case (type lambda-list &key before-unwind after-unwind)
"Helper for the HANDLER-CASE* macro. This one creates the HANDLER-CASE handler-clauses out of the :AFTER-UNWIND form"
(declare (ignorable before-unwind))
(if after-unwind
`(,type ,lambda-list (declare (ignorable ,@lambda-list)) ,after-unwind))))
(defmacro handler-case* (form &rest cases)
"Like HANDLER-CASE and HANDLER-BIND rolled into one. Example usage:
(handler-case*
(restart-case
(error \"ZOMG! ERROR!\")
(fuck-it () 'ignored))
(t (condition)
:before-unwind
(progn (format t \"An error occurred Ignore it (y/N)? \")
(if (eq (read) 'y)
(invoke-restart 'fuck-it)))
:after-unwind
(format t \"You just couldn't fucking ignore it, could you?~%\")))
:before-unwind is, of course, executed before the stack unrolls, so you can
invoke restarts from there. If no restart is invoked, the error falls through
to the :after-unwind case, where you can handle it like a regular handler-case.
The above paragraph is not 100% accurate: If the :BEFORE-UNWIND case does not
invoke a restart, another HANDLER-CASE or HANDLER-CASE* form may get control
of the error *before* the :AFTER-UNWIND case:
(defun handles-own-error ()
(handler-case
(error \"ZOMG! ERROR!\")
(t () :i-got-this)))
(handler-case*
(restart-case
(handles-own-error)
(fuck-it () 'ignored))
(t (condition)
:before-unwind
(progn (format t \"An error occurred Ignore it (y/N)? \")
(if (eq (read) 'y)
(invoke-restart 'fuck-it)))
:after-unwind
(format t \"You just couldn't fucking ignore it, could you?~%\")))
In this case, first the :BEFORE-UNWIND case is evaluated, and then the error is given
to the HANDLER-CASE form *inside* HANDLES-OWN-ERROR. The :AFTER-UNWIND case is never
evaluated.
If no :after-unwind form is provided and no restart is invoked, the condition is not trapped."
`(handler-case
(handler-bind ,(remove nil (mapply #'expand-handler-bind cases))
,form)
,@(remove nil (mapply #'expand-handler-case cases))))
Provides: HANDLER-CASE*
Requires: MAPPLY
Author: Jeremy Phelps phelpsj@nuvox.net
License: Public Domain
The text was updated successfully, but these errors were encountered:
;; Write the code here.
Provides: HANDLER-CASE*
Requires: MAPPLY
Author: Jeremy Phelps phelpsj@nuvox.net
License: Public Domain
The text was updated successfully, but these errors were encountered: