为什么要学习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)))
我应该在这里和那里(在哪里,如何)插入println
;或者是否有建议的工作流程/工具?
答案 0 :(得分: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
它不会捕获内部函数等(正如Charles所指出的那样),并且可能会对大型代码图表产生压力,但在探索小型代码图时,它可能非常方便。
(如果感兴趣的组与名称空间不完全对齐,也可以跟踪单独选择的Vars。)
答案 1 :(得分:6)
Sayid是Clojure Conj 2016上展示的工具,它直接适用于此目的,并附带一个优秀的Emacs插件。请参阅the talk at which it was presented。
要查看瞬态函数的内部调用,请参阅ws-add-inner-trace-fn
(之前为ws-add-deep-trace-fn
)。
答案 2 :(得分:4)
出于此目的,我经常使用来自the Tupelo library的spyx
和相关函数,例如spy-let
:
(ns tst.clj.core
(:require [tupelo.core :as t] ))
(t/refer-tupelo)
(defn kadane [coll]
(spy-let [ pos+ (fn [sum x] (if (neg? sum) x (+ sum x)))
ending-heres (reductions pos+ 0 coll) ]
(spyx (reduce max ending-heres))))
(spyx (kadane (range 5)))
将产生输出:
pos+ => #object[tst.clj.core$kadane$pos_PLUS___21786 0x3e7de165 ...]
ending-heres => (0 0 1 3 6 10)
(reduce max ending-heres) => 10
(kadane (range 5)) => 10
恕我直言,很难打败一个简单的println
或类似的调试。随着您接近生产,日志文件也非常宝贵。
答案 3 :(得分:4)
如果您像大多数Clojurians一样使用带有CIDER的Emacs,那么您已经有了内置的调试器:
https://github.com/clojure-emacs/cider/blob/master/doc/debugging.md
很可能是您最喜欢的IDE /编辑器内置了一些内容或者已经有插件。
还有(没有特别的顺序):
println
我先看看上面的内容。然而,还有其他可能性:
此外,如果函数足够简单,您可以在开发时添加def
以在函数内的给定时间内查看绑定内部。