Below is a ps macro that simulates the shadowing of special variables in
Lisp. I'm wondering if anyone thinks this would be useful to add to
Parenscript.
I wrote it because I have some Javascript functions that reference global
variables, and wanted to write some test functions for those without
modifying global state. One option of course would be to simply write the
original functions to take parameters instead of the global variables. But
that complicates their signatures and I'm loath to modify production code to
suit tests. With this macro, my test can do this:
(ps (shadow-let ((*global-var* "test value"))
(function-that-uses-global-var)))
and the original value of *global-var* will be restored:
var _js3778 = null;
try {
_js3778 = GLOBALVAR;
GLOBALVAR = 'test value';
functionThatUsesGlobalVar();
} finally {
GLOBALVAR = _js3778;
};
Daniel
------------------------------------------------------------------------
(defpsmacro shadow-let (bindings &body body)
(labels ((wrap-expr (bindings body)
(if (null bindings)
body
(list (list 'temporarily-bind (car bindings) (wrap-expr (cdr bindings)
body))))))
`(macrolet ((temporarily-bind ((var expr) body)
(with-ps-gensyms (temp)
`(progn (defvar ,temp nil)
(try (progn (setf ,temp ,var)
(setf ,var ,expr)
,@body)
(:finally (setf ,var ,temp)))))))
,(cons 'progn (wrap-expr bindings body)))))