2013-02-19 50 views
7

很多时候,当我尝试写一些函数时,我得到了异常。这很正常。在Java中,你可以找到发生异常的位置和原因,但clojure异常文本让我发疯。是否有一些提示如何读取clojure中的异常以及如何查找代码异常发生的位置以及为什么?如何读取REPL中的clojure异常?

例如,我会采取一些代码:

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

,当我在REPL调用这个函数我会得到

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

不帮我多找在第二行的问题。在更复杂的代码中,它几乎不会提供任何信息。 (当然它会告诉看看列表?在一些参数中有错误的数目)。我尝试在REPL中编写代码是错误的吗?如何读取REPL中的异常消息?有没有办法在REPL中获得有关异常的更好信息?

+0

http://stackoverflow.com/questions/2352020/debugging-in-clojure的可能重复。 – 2013-02-19 14:52:50

+0

也与http://stackoverflow.com/questions/14297079/why-are-clojure-stacktraces-so-long/14298576#14298576相关 – JohnJ 2013-02-19 22:43:02

回答

2

采集org.clojure/tools.trace

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

让我们尝试dotrace(改变了起来,为了让事情更有趣):

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) 

嗯......

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

让我们再试一次:

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) 

啊哈!在例外之前将其设置为(list?)

6

您可以使用clojure.stacktracehttp://richhickey.github.com/clojure/clojure.stacktrace-api.html

用法:

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

输出:

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