Clojure编译时​​转义机制

时间:2010-10-22 11:37:54

标签: debugging compiler-construction clojure

Forth语言提供了一种“编译时”转义机制,可以在编译器运行时(不是在运行时)立即执行代码。例如,您可以包含print语句来调试棘手的语法或输入错误。)

Clojure有类似的东西吗?我在我的一个函数调用中得到一个编译时IllegalArgumentException,并希望添加一个编译时print语句来确定参数类型((.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有效:

(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 个答案:

答案 0 :(得分:2)

在编译期间打印类别非常局限于特殊情况。你将主要获得符号和序列号。在编译期间,只有文字具有有意义的类型。您可以在编译期间通过宏执行任意代码。

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

然而正如我所说:这通常不是很有帮助。不,通常你不能将x包裹在eval中,例如。如果x是一个引用let-local的符号。

编辑:更新更新的问题。

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

试试这个。不需要功能。 <{1}}内的def应该敲响警钟。