clojure:#'/(var ...)形式的用途是什么?

时间:2011-03-28 16:36:56

标签: clojure

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-methodif-route函数定义为defn- s。

我不明白#'函数中compile-route的含义。 (var ...)的文档说:

  

符号必须解析为var,并返回Var对象本身(不是其值)。读者宏#'x扩展为(var x)。

但对我而言,在发生的事情(即从defmacro调用)的背景下,它听起来就像是意味着将返回符号的值,这与可替代性听起来的相同:

(def x 5)
(+ x 7)
-> 12

即,(+ x 7)扩展为(+ 5 7)

或与{{1}}

相同

我在这里缺少什么?

2 个答案:

答案 0 :(得分:4)

在看了一会儿之后,我开始怀疑它与if-methodif-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