aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Okay <okay@toyful.space>2022-03-20 07:47:17 -0500
committerColin Okay <okay@toyful.space>2022-03-20 07:47:17 -0500
commit4456c2f10407e3f2290c4a8027fb9c9980820b68 (patch)
tree41cf0d1bfacce922621366525537ebcca5ddfe22
parentb19b9f2ba733790b1d8194aa9f3bba04a8e1df3f (diff)
refactor defun/t to use symbol-function values, and restart-case
-rw-r--r--clpmfile6
-rw-r--r--testiere.lisp22
2 files changed, 21 insertions, 7 deletions
diff --git a/clpmfile b/clpmfile
new file mode 100644
index 0000000..3e087ff
--- /dev/null
+++ b/clpmfile
@@ -0,0 +1,6 @@
+;;; -*- Mode: common-lisp; -*-
+(:api-version "0.4")
+
+(:source "quicklisp" :url "https://beta.quicklisp.org/dist/quicklisp.txt" :type :quicklisp)
+
+(:asd "testiere.asd")
diff --git a/testiere.lisp b/testiere.lisp
index 003647c..8bdd526 100644
--- a/testiere.lisp
+++ b/testiere.lisp
@@ -59,17 +59,25 @@
(list (mapcar (lambda (spec) (build-test name spec)) specs)
(append before after))))))
+
(defmacro defun/t (name lambda-list &body body)
"Like regular DEFUN, but with embedded unit tests. If those tests
would fail, the function fails to be defined. "
(destructuring-bind (tests function-body) (extract-tests name body)
- `(labels ((,name ,lambda-list ,@function-body))
- (handler-case
- (progn ,@tests
- (defun ,name ,lambda-list ,@function-body))
- (error (e)
- (invoke-debugger e)
- )))))
+ (let ((cached (gensym)))
+ `(let ((,cached
+ (when (fboundp ',name)
+ (symbol-function ',name))))
+ (restart-case
+ (progn
+ (defun ,name ,lambda-list ,@function-body)
+ ,@tests)
+ (make-unbound () (fmakunbound ',name))
+ (revert-to-last-good-version ()
+ (if ,cached
+ (setf (symbol-function ',name)
+ ,cached)
+ (fmakunbound ',name))))))))