2013-02-19 17 views
7

Wiele razy, gdy próbuję napisać jakąś funkcję, otrzymuję wyjątek. To normalne. W Javie możesz znaleźć miejsce i powody, dla których wyjątek się pojawia, ale w tekstach wyjątków clojure po prostu mnie oszalam. Czy jest kilka wskazówek, jak odczytywać wyjątki w clojure i jak znaleźć miejsce w wyjątku kodu i dlaczego?Jak odczytać wyjątki clojure w REPL?

Na przykład wezmę jakiś kod:

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

kiedy wywołać tę funkcję w REPL dostanę

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

które nie pomagają mi dużo, aby znaleźć problem w drugiej linii. W nieco bardziej skomplikowanym kodzie nie da prawie żadnych informacji. (Oczywiście, że mówi na liście? W niektórych jest błędna liczba argumentów.) Czy to źle, że próbuję napisać kod w REPL? Jak czytać komunikaty wyjątków w REPL? Czy istnieje sposób uzyskania lepszych informacji na temat wyjątków w REPL?

+0

Możliwe duplikaty http://stackoverflow.com/questions/2352020/debugging-in-clojure. –

+0

Związany również z http://stackoverflow.com/questions/14297079/why-are-clojure-stacktraces-so-long/14298576#14298576 – JohnJ

Odpowiedz

2

Acquire org.clojure/tools.trace.

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

Spróbujmy dotrace (zmieniła się kolejność, aby rzeczy bardziej interesujące):

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? 

Spróbujmy jeszcze raz:

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) 

Aha! Zrobiłem to przed (list?) przed wyjątkiem.

6

Można użyć clojure.stacktrace: http://richhickey.github.com/clojure/clojure.stacktrace-api.html

Zastosowanie:

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

wyjściowa:

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