2017-08-23 88 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)))))