当用Java等命令式编程语言编程时,可以方便地添加跟踪语句.例如:
for (int i=0; i<10; i++) {
// do something
// do something
System.out.println("Some trace statement");
// do something
}
Run Code Online (Sandbox Code Playgroud)
如何通过Clojure等LISP方言实现这一目标 - 例如说我想在重复之前添加一个跟踪:
(def fact
(fn [n]
(loop [cnt n acc 1]
(if (zero? cnt)
acc
;; say I want to add a trace here
(recur (dec cnt) (* acc cnt))))))
Run Code Online (Sandbox Code Playgroud)
笔记:
Lisp环境通常提供交互式调试环境和跟踪机制.例如,在SBCL中,您可以使用跟踪宏: 您甚至不需要像在Java示例中那样修改代码.
对于Clojure,请查看tools.trace库或以下答案:clojure:向命名空间中的每个函数添加调试跟踪?
另请参阅此问题的许多答案:在Clojure中进行调试? 其中大多数都涉及将要调试/跟踪的表达式嵌套在另一个表达式中,如Chiron建议的那样.
我不认为" 我必须重新格式化并适当地关闭括号 "是一个很好的论点; 每次编辑程序时都必须处理语法,否则您将不会修改代码.
我个人不使用我现在是Paredit的快乐用户.您的编辑在编码时会跟踪parens和括号,这非常方便.
我真的不想把你的表达式嵌入到另一个表达式中,我想你可以编写一个读取器宏,这样你就可以用一个调试语句来注释一个表达式,但这有点矫枉过正,imho(编辑:这是spyscope所做的,显然;参见NielsK的答案).
该Spyscope库提供用于放入微量打印,而无需改变原有的语法,只需在你(和其他许多人)喜欢的方式一个简单的选择.
spyscope.repl=> (take 20 (repeat #spy/p (+ 1 2 3)))
6
(6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6)
Run Code Online (Sandbox Code Playgroud)
还有包含跟踪消息的方法
spyscope.repl=> #spy/d ^{:marker "triple-add"} (+ 1 2 3)
spyscope.repl$eval3935.invoke(NO_SOURCE_FILE:1) triple-add (+ 1 2 3) => 6
6
Run Code Online (Sandbox Code Playgroud)
甚至(部分)堆栈跟踪
spyscope.repl=> (take 20 (repeat #spy/d ^{:fs 3} (+ 1 2 3)))
----------------------------------------
clojure.lang.Compiler.eval(Compiler.java:6477)
clojure.lang.Compiler.eval(Compiler.java:6511)
spyscope.repl$eval675.invoke(REPL:13) (+ 1 2 3) => 6
(6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
324 次 |
| 最近记录: |