在compojure library in the core namespace中,我看到以下表单:
(defn- compile-route
"Compile a route in the form (method path & body) into a function."
[method route bindings body]
`(#'if-method ~method
(#'if-route ~(prepare-route route)
(fn [request#]
(let-request [~bindings request#]
(render (do ~@body) request#))))))
和
(defmacro GET "Generate a GET route."
[path args & body]
(compile-route :get path args body))
在文件中,if-method
和if-route
函数定义为defn-
s。
我不明白#'
函数中compile-route
的含义。 (var ...)
的文档说:
符号必须解析为var,并返回Var对象本身(不是其值)。读者宏#'x扩展为(var x)。
但对我而言,在发生的事情(即从defmacro调用)的背景下,它听起来就像是意味着将返回符号的值,这与可替代性听起来的相同:
(def x 5)
(+ x 7)
-> 12
即,(+ x 7)
扩展为(+ 5 7)
我在这里缺少什么?
答案 0 :(得分:4)
在看了一会儿之后,我开始怀疑它与if-method
和if-route
函数实际上是私有的这一事实有关((defn- if-route ...)
)
此外,对于宏,当您执行反向引号(“`”)时,您实际上在最终扩展中获得了完全命名空间指定的符号:
`(+ 2 3)
将扩展为
(clojure.core/+ 2 3)
由于这些方法是私有的,因此在正常扩展中无法访问它们,因此使用var函数来获取符号,该符号包含对扩展中此时必须调用的实际函数的引用。
答案 1 :(得分:3)
ring-reload
可以从您在开发期间不断修改的文件中重新加载var定义。由于您传递了一个(var ...),每次尝试读取它时都会解析它,因此可以在每次请求时重新读取重新加载的变量。这导致交互式Web开发(无需编译等)如果您不使用(var ...)而是直接传递值,则重新加载的变量将不会传递给环URI处理程序,因此您不能简单地修改并运行你的代码。
检查此博客条目,例如:
http://charsequence.blogspot.com/2010/09/interactive-web-development-with.html