这是我的宏定义:
*(defmacro run-test (test)
`(format t "Run test ~a ... ~a" ',test ,test))
*(run-test (= 1 1))
Run test (= 1 1) ... T
NIL
现在一切正常,所以我定义了第二个宏(运行多个测试):
*(defmacro run-tests (&body body)
`(loop for tc in ',body
do (run-test tc)))
* (run-tests (= 2 (1+ 1)) (= 1 1))
Run test TC ... (= 2 (1+ 1) Run test TC ... (= 1 1)
这个结果不是我想要的,我希望 tc
的每个值都被 sexp 替换,并在运行测试中评估该值。我试图更换线路
do (run-test tc)
与
do (run-test ,tc)
但这表示错误
Undefined variable: TC
我怎样才能改变它以获得正确的结果?
最佳答案
查看例如的扩展(运行测试(= 1 1))
:
(loop for tc in '((= 1 1)) do (run-test tc))
如您所见,代码尝试调用 (run-test tc)
。但是 run-test
操作的是一个表单;当您传递包含 表单的变量时,它将不起作用。
如果您将代码更改为 (run-test ,tc)
,您将尝试在宏扩展期间引用 tc
变量,但它仅在运行时绑定(bind)。
一个解决方案是在宏展开时做更多的事情:
(defmacro run-tests (&body body)
`(progn ,@(loop for tc in body collect `(run-test ,tc))))
关于macros - 在宏中取消引用时 undefined variable ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19373134/