【问题标题】:clojure: What's the use of the #'/(var ...) form?clojure:#'/(var ...) 形式有什么用?
【发布时间】:2011-03-28 16:36:55
【问题描述】:

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) 或与(+ 5 7) 相同

我在这里错过了什么?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    看了一段时间后,我开始怀疑这与 if-methodif-route 函数实际上是私有的 ((defn- if-route ...)) 这一事实有关。

    此外,对于宏,当您使用反引号 (" ` ") 时,您实际上会在最终扩展中获得完全命名空间指定的符号:

    `(+ 2 3)
    

    将扩展为

    (clojure.core/+ 2 3)
    

    由于这些方法是私有的,它们在正常扩展中是不可访问的,因此使用 var 函数来获取包含对在扩展中此时必须调用的实际函数的引用的符号.

    【讨论】:

    • 还有一条评论:符号不包含引用。 Vars 可以。这与 Lisp、IIUC 不同。符号只是名称,并由编译器解析为 Vars。该代码有效,因为 Var 将所有 .invoke 调用委托给它所持有的东西。
    【解决方案2】:

    ring-reload 可以从您在开发过程中不断修改的文件中重新加载 var 定义。由于您传递了 (var ...),因此每次尝试读取它时都会解决它,因此可以在每次请求时重新读取重新加载的 var。这会导致交互式 Web 开发(无需编译等)。如果您不使用 (var ...) 而是直接传递值,那么重新加载的变量将不会传递给环 URI 处理程序,因此您不能简单地修改并运行您的代码。

    例如查看此博客条目:

    http://charsequence.blogspot.com/2010/09/interactive-web-development-with.html

    【讨论】:

      猜你喜欢
      • 2015-09-06
      • 1970-01-01
      • 1970-01-01
      • 2019-09-21
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      相关资源
      最近更新 更多