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

Macros 传递给宏的变量在错误的命名空间中得到解析?,macros,clojure,lisp,noir,Macros,Clojure,Lisp,Noir,宏defpage给我带来了一点麻烦。我正在尝试构造一个类似以下内容的调用: (defpage [:post "some/url"] [data] ;; some stuff... ) 但是,我不想使用关键字:post,而是想使用一个变量,如下所示: (def my-method :post) (defpage [my-method "some/url"] [data] ;; some stuff... ) 问题是,当宏展开时,它希望解析compojure.core命名空间中的

defpage
给我带来了一点麻烦。我正在尝试构造一个类似以下内容的调用:

(defpage [:post "some/url"] [data]
  ;; some stuff...
  )
但是,我不想使用关键字
:post
,而是想使用一个变量,如下所示:

(def my-method :post)
(defpage [my-method "some/url"] [data]
  ;; some stuff...
  )
问题是,当宏展开时,它希望解析
compojure.core
命名空间中的变量
my method
,而不是我自己的,这给了我一个错误:

No such var: compojure.core/MY-METHOD

如何强制
我的方法
在当前上下文中解析?

如何将我的方法与它所在的命名空间一起传递:

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

看起来,noir并不打算以这种方式使用,因为它接受method参数并将其转换为
compojure.core
中的符号(请参阅)。这意味着,这里不需要变量,只需要文本。因此,我认为你对此无能为力,除了将一期文章发布到noir…

我想这是一个与以下类似的问题: 宏可以对其参数执行任何操作,因此在中传递裸符号可能会导致不可预知的结果

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

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

请注意,我的方法在这里不是一个文本,所以在进入eval之前,它首先在我们自己的名称空间中得到解析和求值。

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