2017-08-23 161 views
1

也许我试图在这里过于富有创意。动态变量的阴影部分

是否有可能扩展动态结合SETF能够地方动态变量的的概念,所以,我可以LET绑定阴影部分动态变量(如plist中)?

例如,我想可以这样做:

(defparameter *foo* '(:one 1)) 

(let (((getf *foo* :one) 2)) 
    (do-things)) 

要隐藏的价值:用2

这个例子之一,因为(getf *foo* :one)不工作是不是LET可以赋值的变量名,但也许有另一种方式?

+0

在Plist档案的情况下,和alist,你可以隐藏以前的绑定,而不是修改底层的列表(这可能是并发/重入代码有问题):'(let((* foo *(list *:one 2 * foo *)))... )' – coredump

回答

4

没有标准方式,但有些实现可能会提供 扩展名,例如letf

或者,你可以使用 unwind-protect自己:

(let ((old-value (getf *foo* :one))) 
    (unwind-protect 
     (progn (setf (getf *foo* :one) 2) 
       (do-things)) 
    (setf (getf *foo* :one) old-value))) 

如果这是你的代码中常见的操作,你甚至可以定义一个宏:

(defmacro with-one (tmp-one &body body) 
    "Bind (getf *foo* :one) to tmp-one around body." 
    (let ((old-value (gensym "WITH-ONE-OLD"))) 
    `(let ((,old-value (getf *foo* :one))) 
     (unwind-protect 
      (progn (setf (getf *foo* :one) ,tmp-one) 
        ,@body) 
     (setf (getf *foo* :one) ,old-value)))))