<div>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.</div>
<div> </div>
<div>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:
</div>
<div> </div>
<div> (ps (shadow-let ((*global-var* "test value"))<br> (function-that-uses-global-var)))</div>
<div> </div>
<div>and the original value of *global-var* will be restored:</div>
<div> </div>
<div> var _js3778 = null;<br> try {<br> _js3778 = GLOBALVAR;<br> GLOBALVAR = 'test value';<br> functionThatUsesGlobalVar();<br> } finally {<br> GLOBALVAR = _js3778;<br> };</div>
<div> </div>
<div>Daniel</div>
<div> </div>
<div>------------------------------------------------------------------------</div>
<div> </div>
<div>(defpsmacro shadow-let (bindings &body body)<br> (labels ((wrap-expr (bindings body)<br> (if (null bindings)<br> body<br> (list (list 'temporarily-bind (car bindings) (wrap-expr (cdr bindings) body))))))
<br> `(macrolet ((temporarily-bind ((var expr) body)<br> (with-ps-gensyms (temp)<br> `(progn (defvar ,temp nil)<br> (try (progn (setf ,temp ,var)<br> (setf ,var ,expr)<br> ,@body)<br> (:finally (setf ,var ,temp)))))))
<br> ,(cons 'progn (wrap-expr bindings body)))))</div>