如何在Clojure中跟踪代码执行?

bla*_*ned 3 debugging clojure

为什么要学习Clojure,我有时需要看看每个步骤的功能是什么.例如:

(defn kadane [coll]
   (let [pos+ (fn [sum x] (if (neg? sum) x (+ sum x)))
         ending-heres (reductions pos+ 0 coll)]
     (reduce max ending-heres)))
Run Code Online (Sandbox Code Playgroud)

我应该println在这里和那里插入(在哪里,如何); 或者是否有建议的工作流程/工具?

Mic*_*zyk 10

这可能不是你在单个函数级别上所追求的(参见下面的Charles Duffy的评论),但如果你想了解一个命名空间(或几个)级别的内容,你可以使用tools.trace(披露:我是贡献者):

(ns foo.core)

(defn foo [x] x)
(defn bar [x] (foo x))

(in-ns 'user) ; standard REPL namespace

(require '[clojure.tools.trace :as trace])
(trace/trace-ns 'foo.core)

(foo.core/bar 123)
TRACE t20387: (foo.core/bar 123)
TRACE t20388: | (foo.core/foo 123)
TRACE t20388: | => 123
TRACE t20387: => 123
Run Code Online (Sandbox Code Playgroud)

它不会捕获内部函数等(正如Charles所指出的那样),并且可能会被大型代码图压倒,但是在探索小型代码图时它可能非常方便.

(如果感兴趣的组与名称空间不完全对齐,也可以跟踪单独选择的Vars.)


Cha*_*ffy 6

Sayid是Clojure Conj 2016上展示的工具,它直接适用于此目的,并附带一个优秀的Emacs插件.看看它的演讲.

要查看瞬态函数的内部调用,请参阅ws-add-inner-trace-fn(之前的ws-add-deep-trace-fn).

  • sayid的作者在这里.我只是想留下一张便条,鼓励任何尝试使用sayid的人与他们遇到的任何问题或问题取得联系(github问题,电子邮件,推特).谢谢 (2认同)

nha*_*nha 5

如果您像大多数 Clojurians 一样使用带有 CIDER 的 Emacs,那么您已经有一个内置的调试器:

https://github.com/clojure-emacs/cider/blob/master/doc/debugging.md

很有可能你最喜欢的 IDE/编辑器已经内置了一些东西或插件。

还有(排名不分先后):

我会先看看上面的。然而,还有/还有其他可能性:

此外,如果函数足够简单,您可以def在开发时添加s 以查看函数内给定时间的绑定内部。