如何检查变量是否在let构造之前定义?Elisp:bounds in let
(let (((if (boundp 'a)
'a
'dummy) t))
(message "I made this work"))
我所试图做的是检查是否如果它已经,将其绑定到本地t
是a
前界。否则根本不在乎a
。
如何检查变量是否在let构造之前定义?Elisp:bounds in let
(let (((if (boundp 'a)
'a
'dummy) t))
(message "I made this work"))
我所试图做的是检查是否如果它已经,将其绑定到本地t
是a
前界。否则根本不在乎a
。
的代码失败:(wrong-type-argument symbolp (if (boundp (quote a)) (quote a) (quote dummy)))
,表明let
特殊形式*不计算这样的说法(尽管该列表将评估为一个符号,列表本身不是一个符号)。
这是一个简单但有缺陷的替代方法,它为a
创建一个本地绑定,但是如果它本来是未绑定的,则将其解除绑定到本地范围。
(let ((a (if (boundp 'a) t nil)))
(or a (makunbound 'a))
;; do things
)
的缺陷是,如果a
最初是未绑定的,你想的是本地范围内的分配a
活得比局部范围,它不会使用这种方法。
起初,我想你需要放弃let
完全避开这个问题,只是用这样的:
(when (boundp 'a)
(setq a-backup a
a t))
;; do things
(when (boundp 'a-backup)
(setq a a-backup)
(makunbound 'a-backup))
后来我才意识到,由于有这么多的东西,宏是回答:
(defmacro let-if-bound (var value &rest body)
"Bind variable VAR to VALUE only if VAR is already bound."
(declare (indent 2))
`(if (boundp ',var)
(let ((,var ,value))
,@body)
(progn ,@body)))
(let-if-bound a t
;; do things
)
(*)A “特殊形式” 是特殊标记,以便其 参数不评估所有原始功能。大多数特殊形式定义了控制 结构或执行变量绑定 - 功能不能 做的事情。
每个特殊形式都有其自己的规则,其参数评估为 ,并且在没有评估的情况下使用哪些参数。评估的特定参数是否为 可能取决于评估其他参数的结果。
@phills所有谢谢回答的第一个。我理解let构造的局限性。我也认为你身边的工作提到了。我只是不喜欢耦合绑定和解除绑定相同的表达式。 – kindahero 2012-03-21 05:22:07
编辑了该问题以修正括号。在接受之前我会再等一会儿。 – kindahero 2012-03-21 05:27:45
最后我明白了......看到编辑答案。 – phils 2012-03-21 06:01:11