我正在尝试创建一个宏来创建一个带有S表达式的函数,并在fixture的词汇上下文中对它们进行求值。这是我写的宏:
(defmacro def-fixture (name bindings)
"Return a function that takes the form to execute but is wrapped between a let of the bindings"
`(defun ,(intern (symbol-name name)) (body)
(let (,bindings)
(unwind-protect
(progn
body)))))
但是当我运行它时,它似乎是在我提供的词汇上下文之外执行
(def-fixture test-fixture '(zxvf 1))
(test-fixture '(= zxvf 1))
let: Symbol's value as variable is void: zxvf
顺便说一下,我启用了变量词法绑定。关于我的错误是什么想法?
答案 0 :(得分:2)
这与词法范围无关。您的宏调用扩展为:
(defun test-fixture (body)
(let ((quote (zxvf 1)))
(unwind-protect (progn body))))
这当然不是你想要的。我不相信(test-fixture '(= zxvf 1))
表示您引用的错误(即variable is void
)。相反,呼叫信号(void-function zxvf)
,因为它试图评估(zxvf 1)
。永远不会评估(= zxvf 1)
表达式,因为它已被引用。
您可能想尝试更多类似的内容:
(defmacro def-fixture (name bindings)
"Return a macro that takes the form to execute but is wrapped between a let of the bindings"
`(defmacro ,name (body)
`(let (,',bindings)
(unwind-protect
(progn
,body)))))
然后将其用作:
(def-fixture test-fixture (zxvf 1))
(test-fixture (= zxvf 1))
答案 1 :(得分:1)
以下注释位于emacs manual:
此外,defun或defmacro正文中的代码无法参考 周围的词汇变量。
可能是你的问题所在。
此外,我不知道您是否需要引用def-fixture
的第二个参数。我使用macrostep
包检查生成的宏,如果没有引号,结果似乎更好。