传递给宏的变量在错误的命名空间中解析?

时间:2011-12-03 23:21:21

标签: macros clojure lisp noir

Noirdefpage给了我一点麻烦。我正在尝试构建一个类似于此的调用:

(defpage [:post "some/url"] [data]
  ;; some stuff...
  )

但是,我不想使用关键字:post,而是使用变量,如下所示:

(def my-method :post)
(defpage [my-method "some/url"] [data]
  ;; some stuff...
  )

问题是当宏扩展时,它想要解析my-method命名空间中的变量compojure.core而不是我自己的变量{+ 1}},这给了我错误:

No such var: compojure.core/MY-METHOD

如何强制my-method在当前上下文中解析?

4 个答案:

答案 0 :(得分:1)

看来,noir并不意味着以这种方式使用,因为它接受方法参数并将其转换为compojure.core中的符号(参见https://github.com/ibdknox/noir/blob/master/src/noir/core.clj#L36)。这意味着,它不期望这个地方的变量,只有文字。所以我不认为你可以做任何事情,除了将问题发布到黑色......

答案 1 :(得分:1)

我想这是一个类似的问题:How can I apply clojure's doc function to a sequence of functions 宏可以用它的args做任何想做的事情,所以传入一个裸符号会导致不可预测的结果。

解决问题的一种方法,但它并不漂亮:

(eval (list 'defpage (vector my-method "some/url") '[data]
  ; some stuff
))

请注意,my-method在这里不是文字,因此在进入eval之前首先在我们自己的命名空间中解析和评估。

答案 2 :(得分:1)

如果我们查看noir / core.clj文件(source),找到parse-route函数并说明它的方法参数(在那里称为action),我们可以发现方法关键字是转换为字符串,大写并在compojure.core命名空间中解析。所有这些都是在宏扩展时完成的。因此,在不改变noir代码的情况下,不可能使用变量而不是关键字。

答案 3 :(得分:0)

如何将my-method与名称空间一起传递到:

(defpage [myns/my-method "some/url"] [data]
;;
)