2013-02-19 12 views
7

Molte volte quando provo a scrivere qualche funzione ottengo un'eccezione. È normale In Java puoi trovare il luogo e il motivo per cui l'eccezione si verifica ma nei testi delle eccezioni dei clojure mi fai impazzire. C'è qualche consiglio su come leggere le eccezioni in clojure e come trovare dove avviene l'eccezione di codice e perché?Come leggere le eccezioni del clojure in REPL?

Per esempio mi prenderò un po 'di codice:

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

quando chiamo questa funzione in REPL mi metterò

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

che non mi aiuta molto a trovare il problema in seconda linea. Nel codice un po 'più complicato non darà quasi nessuna informazione. (Ovviamente indica la lista? In alcuni c'è un numero sbagliato di argomenti.) È sbagliato che provi a scrivere codice in REPL? Come leggere i messaggi di eccezione in REPL? C'è un modo per ottenere informazioni migliori sulle eccezioni in REPL?

+0

Possibile duplicato di http://stackoverflow.com/questions/2352020/debugging-in-clojure. –

+0

Relativo anche a http://stackoverflow.com/questions/14297079/why-are-clojure-stacktraces-so-long/14298576#14298576 – JohnJ

risposta

2

Acquire org.clojure/tools.trace.

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

Proviamo un dotrace (cambiato l'ordine di rendere le cose più interessanti):

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? 

Proviamo di nuovo:

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! Fatto a (list?) prima dell'eccezione.

6

È possibile utilizzare clojure.stacktrace: http://richhickey.github.com/clojure/clojure.stacktrace-api.html

Usage:

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

uscita:

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 
Problemi correlati