On 11/6/07, Daniel Gackle <
danielgackle@gmail.com> wrote:
> 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)))))