Как читать исключения clojure в REPL?
много раз, когда я пытаюсь написать функцию, я получаю исключение. Это нормально. В Java вы можете найти место и причину, почему происходит исключение, но в текстах исключений clojure просто сводят меня с ума. Есть ли несколько советов, как читать исключения в 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)
которые не очень помогают мне найти проблема во второй строке. В немного более сложном коде он не даст почти никакой информации. (Конечно, это говорит look at list? в некоторых есть неправильное количество аргументов.) Это неправильно, что я пытаюсь написать код в REPL? Как читать исключения mesages в REPL? Есть ли способ получить лучшую информацию об исключениях в REPL?
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?)
до исключения.
можно использовать clojure.stacktrace
: http://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