2017-08-23 8 views
1

多分私はここで創造的であるようにしています。動的変数のシャドーイング部分

は、それは私がLETバインディングでの一部に(などのplistなど)動的変数をシャドウすることができるように、動的変数のSETFでき場所に動的バインディングの概念を拡張することは可能ですか? (getf *foo* :one)ではないので、2

と1この例では動作しません:の値がシャドウする

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

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

例えば、私のような何かをできるようにしたいと思います変数名はLETに値を割り当てることができますが、おそらく別の方法がありますか?

+0

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

をこれはあなたのコード内の一般的な操作である場合は、あなたもそのためのマクロを定義できますあなたが元のリストを変更するのではなく、並行した/再入可能なコードで問題になるかもしれない) '(let((* foo *(list *:one 2 * foo *))))...) ) ' – coredump

答えて

4

標準的な方法はありませんが、一部の実装では という拡張子を提供する場合があります(例:letf)。

また、あなたが unwind-protectを自分で使用することができます。プレースメントリストの場合は

(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))))) 
関連する問題