2013-02-19 70 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