2013-02-19 12 views
7

Bazı işlevler yazmaya çalıştığımda çoğu kez özel durum alıyorum. Bu normal. Java'da istisnanın neden ortaya çıktığı, ancak clojure istisna metinlerinde beni çıldırttığınız yeri ve sebebi bulabilirsiniz. Clojure'deki istisnaları nasıl okuyacağınız ve kod istisnasının nerede olduğunu ve niçin bulunacağını öğrenmek için bazı ipuçları var mı?REPL'deki clojure istisnaları nasıl okunur?

Örneğin bazı kod alacaktır: Ben Çoğaltma bu işlevi çağırdığınızda

(do 
(list?) 
(list? []) 
(list? '(1 2 3)) 
(list? (defn f [] (do()))) 
(list? "a")) 

beni çok ikinci satırında sorunu bulmaya yardımcı olmazsa

java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$list-QMARK- (NO_SOURCE_FILE:46) 

alacak. Biraz daha karmaşık kodlarda neredeyse hiç bilgi vermez. (Tabii ki listeye bakar, bazılarında yanlış argüman vardır.) REPL'ye kod yazmayı denediğim yanlış mı? REPL'deki istisna mesajları nasıl okunur? REPL'teki istisnalar hakkında daha iyi bilgi edinmenin yolu var mı?

+0

Olası http://stackoverflow.com/questions/2352020/debugging-in-clojure kopyası. –

+0

Ayrıca, http://stackoverflow.com/questions/14297079/why-are-clojure-stacktraces-so-long/14298576#14298576 ile ilgilidir. – JohnJ

cevap

2

Edinme org.clojure/tools.trace.

user=> (dotrace [list?] 
    #_=> (do 
    #_=> (list? []) 
    #_=> (list? '(1 2 3)) 
    #_=> (list?) 
    #_=> (list? (defn f [] (do()))) 
    #_=> (list? "a")) 
    #_=>) 
IllegalStateException Can't dynamically bind non-dynamic var: clojure.core/list? 
    clojure.lang.Var.pushThreadBindings (Var.java:353) 

Hmm ...

user=> (.setDynamiC#'list?) 
#'clojure.core/list? 

Hadi bir daha deneyelim:

user=> (dotrace [list?] 
    #_=> (do 
    #_=> (list? []) 
    #_=> (list? '(1 2 3)) 
    #_=> (list?) 
    #_=> (list? (defn f [] (do()))) 
    #_=> (list? "a"))) 
TRACE t1216: (list? []) 
TRACE t1216: => false 
TRACE t1217: (list? (1 2 3)) 
TRACE t1217: => true 
TRACE t1218: (list?) 
ArityException Wrong number of args (0) passed to: core$list-QMARK- 
    clojure.lang.AFn.throwArity (AFn.java:437) 

user=> (use 'clojure.tools.trace) 

en bir dotrace (şeyler daha ilginç hale getirmek için sipariş kadar değişti) deneyelim

Aha! İstisnadan önce (list?) yaptık.

6

Sen clojure.stacktrace kullanabilirsiniz: http://richhickey.github.com/clojure/clojure.stacktrace-api.html

Kullanımı:

(use 'clojure.stacktrace) 
(/ 1 0) 
(e) 

Çıktı:

java.lang.ArithmeticException: Divide by zero 
at clojure.lang.Numbers.divide (Numbers.java:156) 
    clojure.lang.Numbers.divide (Numbers.java:3691) 
    user$eval954.invoke (NO_SOURCE_FILE:1) 
    clojure.lang.Compiler.eval (Compiler.java:6511) 
    clojure.lang.Compiler.eval (Compiler.java:6477) 
    clojure.core$eval.invoke (core.clj:2797) 
    clojure.main$repl$read_eval_print__6405.invoke (main.clj:245) 
    clojure.main$repl$fn__6410.invoke (main.clj:266) 
nil