私はClojureでユーザー定義の例外を作成しようとしていて、あらゆる種類の問題を抱えています。ここで概説した方法を試しました。
http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#User-Defined_Exceptions
(gen-and-load-class 'user.MyException :extends Exception)
しかし、それはClojure 1.2では機能しないようです(または私が何か間違ったことをしています...)。私の環境はClojure1.2、Emacs、そしてleinswankです。
ご協力いただきありがとうございます!
以下を含むファイルsrc/user/MyException.clj
(src
はCLASSPATH
上にあります)を作成します。
(ns user.MyException
(:gen-class :extends Java.lang.Exception))
REPLで*compile-path*
の値を確認してください。このディレクトリが存在し、CLASSPATH
にあることを確認してください。ディレクトリが存在しない場合は作成します。 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>
カスタムクラスを生成するのではなく、カスタム例外を使用する2つのはるかに簡単な方法があります。
使用 slingshot -これにより、カスタムのthrow+
およびcatch+
マクロが提供され、任意のオブジェクトと例外をスローおよびキャッチできます。
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 "???"))))
またはmidjeテストで:
(fact "should throw some eels"
(...)
=> (throws clojure.lang.ExceptionInfo
#(= :eels (-> % ex-data :cause))))
FWIW、相互運用上の理由でカスタム例外を作成している場合を除き、代わりにclojure.contrib.condition
の使用を検討することをお勧めします。 APIを使用してカスタムデータをピギーバックするプリコンパイル済みのカスタム例外が付属しています。代わりにそれを使用することで、多くのカスタム例外の作成を回避することができました。ドキュメントはここにあります: http://clojure.github.com/clojure-contrib/condition-api.html