Debugging Clojure编译时转义机制

Debugging Clojure编译时转义机制,debugging,compiler-construction,clojure,Debugging,Compiler Construction,Clojure,Forth语言提供了一种“编译时”转义机制,在这种机制中,当编译器运行时(而不是在运行时),代码可以立即执行。例如,可以包含打印语句来调试复杂的语法或类型错误) Clojure有类似的吗?我在一个函数调用中得到一个编译时IllegalArgumentException,并希望添加一个编译时打印语句以确定参数类型((.getClass)) 谢谢 更新:以下是编译失败的完整defn: (ns my.ns.name (:gen-class :main true) (:use [cl

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

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
工作:

(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"))))

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

(defmacro debug-type
  [x]
  (println (type x))
  x)
然而,正如我所说:这通常不会有很大帮助。和否:一般来说,您不能在
eval
中包装
x
,例如,如果
x
是一个指向本地let的符号

编辑:更新问题的更新

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

试试这个。不需要函数<代码>定义内部
定义
应该会敲响警钟。

mmm在编译时?什么时候aot编译源代码以生成jvm字节码?clojure中没有其他编译时。我认为只有在运行时才可能发生异常,因为公共类IllegalArgumentException扩展了RuntimeException。要在运行时检查类,请在param声明后插入一个(println(type arg))vector@jneira:我正在使用Maven构建项目。肯定是在AOT编译期间发生的。好的,我错过了在运行时抛出异常的java编译器time@kotarak:我正在尝试执行以下代码:
(…my.ns.name(getProtectionDomain)(getCodeSource)(getLocation))
并且在对my.ns.name执行AOT期间,我获得了IllegalArgumentException(“无getProtectionDomain方法”)。如果我将其更改为
(>my.ns.name(.getProtectionDomain)(.getCodeSource)(.getLocation))
有效。算了。@Ralph:Hmm。没有线索。你是否尝试了
*ns*
而不是实际名称?你是否使用
->
清理了两次尝试之间的任何.class文件?@kotarak:更改为
*ns*
将错误移到了运行时:-)。我在运行Maven之前清理了.class文件,并得到了相同的compile-time错误。我在原来的问题中添加了一个更新,显示了无法编译的实际代码。@拉尔夫:我不能用符号引用名称空间。因此,我猜您的两个初始表单都不应该工作。如果在编译时执行代码,问题怎么会转移到运行时?您是说“两个表单”都有“得到相同的c-t错误”还是与前面的
,但不是
->
“?