Clojure中的自定义exception?
我一直试图在Clojure中创build一个用户定义的exception,并且遇到各种各样的问题。 我尝试了这里概述的方法:
http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#User-Defined_Exceptions
(gen-and-load-class 'user.MyException :extends Exception)
但是,这似乎并没有在Clojure 1.2(或我做错了什么…)。 我的环境是Clojure 1.2,Emacs和lein swank。
谢谢你的帮助!
创build一个文件src/user/MyException.clj
(其中src
在CLASSPATH
)包含:
(ns user.MyException (:gen-class :extends java.lang.Exception))
检查REPL处的*compile-path*
的值。 确保此目录存在并位于CLASSPATH
。 创build目录,如果它不存在; Clojure不会为你这样做。
user> *compile-path* "/home/user/foo/target/classes/" user> (System/getProperty "java.class.path") ".......:/home/user/foo/target/classes/:......."
编译你的类:
user> (compile 'user.MyException) user.MyException
如果它工作,在*compile-path*
你现在应该有这样的文件:
/home/user/foo/target/ /home/user/foo/target/classes /home/user/foo/target/classes/user /home/user/foo/target/classes/user/MyException.class /home/user/foo/target/classes/user/MyException__init.class /home/user/foo/target/classes/user/MyException$loading__4410__auto__.class
重新启动你的Clojure REPL / JVM来加载这些类。 再次确保这些新的类文件位于CLASSPATH
。 现在你应该可以使用你的课堂:
user> (user.MyException.) #<MyException user.MyException>
而不是生成自定义类,有两种更简单的方法来使用自定义exception:
-
使用弹弓 – 这提供了自定义的
throw+
和catch+
macros,让你抛出和捕捉任何对象,以及例外。 -
在clojure 1.4及更高版本中,可以使用clojure.core / ex-info和clojure.core / ex-data生成并捕获
clojure.lang.ExceptionInfo
类,该类包装消息和数据映射。
使用这个很简单:
(throw (ex-info "My hovercraft is full of eels" {:type :python-exception :cause :eels})) (try (...) (catch clojure.lang.ExceptionInfo e (if (= :eels (-> e ex-data :cause)) (println "beware the shrieking eels!") (println "???"))))
或者在midjetesting中:
(fact "should throw some eels" (...) => (throws clojure.lang.ExceptionInfo #(= :eels (-> % ex-data :cause))))
FWIW,除非你为互操作的原因创build一个自定义的exception,你可能要考虑使用clojure.contrib.condition
。 它带有一个预编译的自定义exception,可以将自定义数据捎带到使用它的API。 我已经能够避免使用它创build许多自定义exception。 文档在这里: http : //clojure.github.com/clojure-contrib/condition-api.html