3

我正在尝试“获取”clojure 宏并are根据现有are宏编写宏的调整版本。我想要的调整是有签名[argv expr args]而不是[argv expr & args] 所以我试过了

(defmacro are2 [argv expr args] `(clojure.test/are ~arg ~expr ~@args))

哪种有效,除了它需要一个未引用的列表:

(are2 [input] (= 0 input) (1 2 3))

我宁愿期待一个引用列表:

(are2 [input] (= 0 input) '(1 2 3))

但这会导致:

Unable to resolve symbol: quote in this context.

如果我尝试

(are2 [input] (= 0 input) (list 1 2 3))

而是将list其本身作为测试用例进行处理。

我有什么不明白/我怎样才能超越我的宏中的报价

4

1 回答 1

5

'(1 2 3)正在扩展到(quote (1 2 3))其中有一个额外的quote符号和一个太多级别的列表,您可以使用 macroexpand-1 看到:

user> (macroexpand-1 '(are2 [input] (= 0 input) '(1 2 3)))
(clojure.test/are [input] (= 0 input) quote (1 2 3)) 

您可以通过首先将其包装为 int 并休息来从列表中删除报价

 user> (defmacro are2 [argv expr args] 
          `(clojure.test/are ~argv ~expr ~@(first (rest args))))
#'user/are2
user> (macroexpand-1 '(are2 [input] (= 0 input) '(1 2 3)))
(clojure.test/are [input] (= 0 input) 1 2 3) 

然后作为测试运行:

user> (are2 [input] (= 0 input) '(1 2 3)

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:1)
expected: (= 0 1)
  actual: (not (= 0 1))

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:1)
expected: (= 0 2)
  actual: (not (= 0 2))

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:1)
expected: (= 0 3)
  actual: (not (= 0 3))
false 
于 2013-02-14T22:20:02.767 回答