当使用repl时,调试Clojure代码的最佳方法是什么?
当前回答
我有一个调试宏,我觉得非常有用:
;;debugging parts of expressions
(defmacro dbg[x] `(let [x# ~x] (println "dbg:" '~x "=" x#) x#))
你可以把它插入到任何你想看发生了什么和什么时候:
;; Examples of dbg
(println (+ (* 2 3) (dbg (* 8 9))))
(println (dbg (println "yo")))
(defn factorial[n] (if (= n 0) 1 (* n (dbg (factorial (dec n))))))
(factorial 8)
(def integers (iterate inc 0))
(def squares (map #(dbg(* % %)) integers))
(def cubes (map #(dbg(* %1 %2)) integers squares))
(take 5 cubes)
(take 5 cubes)
其他回答
Hugo Duncan和他的合作者继续在ritz项目上做着惊人的工作。Ritz-nrepl是一个具有调试功能的nREPL服务器。在Clojure/Conj 2012上观看Hugo's Debuggers in Clojure talk来查看它的实际操作,在视频中一些幻灯片是不可读的,所以你可能想从这里查看幻灯片。
下面是一个调试复杂let表单的宏:
(defmacro def+
"def with binding (def+ [{:keys [a b d]} {:a 1 :b 2 :d 3}])"
[bindings]
(let [let-expr (macroexpand `(let ~bindings))
vars (filter #(not (.contains (str %) "__"))
(map first (partition 2 (second let-expr))))
def-vars (map (fn [v] `(def ~v ~v)) vars)]
(concat let-expr def-vars)))
...以及一篇解释其用途的文章。
还有dotrace,它允许您查看所选函数的输入和输出。
(use 'clojure.contrib.trace)
(defn fib[n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
(dotrace [fib] (fib 3))
产生输出:
TRACE t4425: (fib 3)
TRACE t4426: | (fib 2)
TRACE t4427: | | (fib 1)
TRACE t4427: | | => 1
TRACE t4428: | | (fib 0)
TRACE t4428: | | => 0
TRACE t4426: | => 1
TRACE t4429: | (fib 1)
TRACE t4429: | => 1
TRACE t4425: => 2
2
在Clojure 1.4中,dotrace已经移动了:
你需要依赖:
[org.clojure/tools.trace "0.7.9"]
(require 'clojure.tools.trace)
您需要将^:dynamic添加到函数定义中
(defn ^:dynamic fib[n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
那鲍勃又成了你的叔叔了
(clojure.tools.trace/dotrace [fib] (fib 3))
TRACE t4328: (fib 3)
TRACE t4329: | (fib 2)
TRACE t4330: | | (fib 1)
TRACE t4330: | | => 1
TRACE t4331: | | (fib 0)
TRACE t4331: | | => 0
TRACE t4329: | => 1
TRACE t4332: | (fib 1)
TRACE t4332: | => 1
TRACE t4328: => 2
来自Java并且熟悉Eclipse,我喜欢逆时针(用于Clojure开发的Eclipse插件)提供的功能:http://doc.ccw-ide.org/documentation.html#_debug_clojure_code
从2016年开始,你可以使用Debux,这是Clojure/Script的一个简单调试库,可以与repl以及浏览器的控制台一起工作。您可以在代码中添加dbg (debug)或clog (console.log)宏,并轻松观察各个函数的结果,等等,打印到您的REPL和/或控制台。
来自项目的Readme:
Basic usage This is a simple example. The macro dbg prints an original form and pretty-prints the evaluated value on the REPL window. Then it returns the value without interfering with the code execution. If you wrap the code with dbg like this, (* 2 (dbg (+ 10 20))) ; => 60 the following will be printed in the REPL window. REPL output: dbg: (+ 10 20) => 30 Nested dbg The dbg macro can be nested. (dbg (* 2 (dbg (+ 10 20)))) ; => 60 REPL output: `dbg: (+ 10 20) => 30` dbg: (* 2 (dbg (+ 10 20))) => 60
推荐文章
- 如何在Visual Studio中找到堆栈跟踪?
- 有一个好的Valgrind Windows的替代品吗?
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?
- Visual Studio:如何打破处理异常?
- 确保您的项目构建设置正在生成一个dSYM文件。对于所有配置,DEBUG_INFORMATION_FORMAT都应该设置为dwarf-with-dsym
- 如何获得GDB中所有线程的回溯?
- 如何检测IE11?
- 如何通过参数和重定向stdin从一个文件到程序运行在gdb?
- 如何在Clojure中创建web应用程序?
- 我如何调试git/git-shell相关的问题?
- Visual Studio拒绝忘记断点?
- 如何在Python自己的调试器(PDB)中执行多行语句
- 我如何在Visual Studio中预处理后看到C/ c++源文件?
- Linux有c++ gdb图形用户界面吗?
- 是什么让Visual Studio调试器停止评估ToString重写?