Debugging Clojure编译时转义机制
Forth语言提供了一种“编译时”转义机制,在这种机制中,当编译器运行时(而不是在运行时),代码可以立即执行。例如,可以包含打印语句来调试复杂的语法或类型错误) Clojure有类似的吗?我在一个函数调用中得到一个编译时IllegalArgumentException,并希望添加一个编译时打印语句以确定参数类型(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
(.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错误”还是与前面的。
,但不是->
“?