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代码的情况下,使用变量代替关键字是不可能的