代码之家  ›  专栏  ›  技术社区  ›  Ralph java.is.for.desktop

Clojure编译时转义机制

  •  1
  • Ralph java.is.for.desktop  · 技术社区  · 14 年前

    Forth语言提供了一种“编译时”转义机制,可以在编译器运行时(而不是运行时)立即执行代码。您可以包括print语句,例如调试复杂的语法或类型错误)。

    Clojure有类似的东西吗?我在一个函数调用中收到一个编译时IllegalArgumentException,希望添加一个编译时打印语句来确定参数类型( (.getClass) ).

    谢谢。

    :这是完整的 defn 编译失败:

    (ns my.ns.name
      (:gen-class
       :main true)
      (:use
       [clojure.contrib.str-utils2 :only (join)])
      (:import
       [java.io PrintWriter]
       [java.net URL]
       [java.util.concurrent Executors]
       [java.util.jar Manifest]
       [org.apache.commons.cli CommandLine HelpFormatter Options Option ParseException PosixParser]))
    
    (defn set-version
      "Set the version variable to the build number."
      []
      (def version
        (-> (str "jar:" (.. my.ns.name (getProtectionDomain)
                                       (getCodeSource)
                                       (getLocation))
                        "!/META-INF/MANIFEST.MF")
          (URL.)
          (.openStream)
          (Manifest.)
          (.. getMainAttributes)
          (.getValue "Build-number"))))
    

    这个 德芬 作品:

    (defn set-version
      "Set the version variable to the build number."
      []
      (println (str (.getClass my.ns.name)))
      (def version
        (-> (str "jar:" (-> my.ns.name (.getProtectionDomain)
                                       (.getCodeSource)
                                       (.getLocation))
                        "!/META-INF/MANIFEST.MF")
          (URL.)
          (.openStream)
          (Manifest.)
          (.. getMainAttributes)
          (.getValue "Build-number"))))
    
    1 回复  |  直到 14 年前
        1
  •  2
  •   kotarak    14 年前

    在编译过程中打印类对象非常局限于特殊情况。你会得到很多符号和序列。在编译期间,只有文字具有有意义的类型。可以通过宏在编译期间执行任意代码。

    (defmacro debug-type
      [x]
      (println (type x))
      x)
    

    不过,正如我所说:这通常不会很有帮助。不:一般来说你不能 x eval ,例如,如果

    编辑: 更新问题。

    (def version
      (-> (str "jar:" (-> *ns* (.getProtectionDomain)
                               (.getCodeSource)
                               (.getLocation))
                      "!/META-INF/MANIFEST.MF")
        (URL.)
        (.openStream)
        (Manifest.)
        (.getMainAttributes)
        (.getValue "Build-number")))
    

    def 里面 defn 应该敲响警钟。