Clojure函数调试的推荐方法是什么?

7

我的当前方法:如果我知道一个函数有bug,我会将它的一些部分复制到REPL中并进行评估,看输出是否符合预期。为了设置它,我必须定义函数的参数作为虚拟输入。这不是非常耗时,但我知道有更高效的方法。

有什么建议吗?


4
刚刚发现并学到了很多相关问题:https://dev59.com/f3E95IYBdhLWcg3wWMdQ。但如果有人对我的具体情况(调试一个“纯函数”输出)有想法,我会“接受”你的好意见!谢谢。 - yayitswei
+1 因为我希望我知道关于Lisp相关语言的任何东西 - JAL
我仍在学习基础知识,但如果我需要跳到调试实际脚本/模块,我会查看一个单元测试包:clojure.contrib.test-is是其中之一;如果我没记错的话还有一两个。 - intuited
5个回答

4

这个宏有帮助吗?它将let转换为一系列的defs,这样你就可以评估子表达式:

(defmacro def-let
  "like let, but binds the expressions globally."
  [bindings & more]
  (let [let-expr (macroexpand `(let ~bindings))
        names-values (partition 2 (second let-expr))
        defs   (map #(cons 'def %) names-values)]
    (concat (list 'do) defs more)))

我在这里写了一个解释: http://www.learningclojure.com/2010/09/astonishing-macro-of-narayan-singhal.html

哦,那真是相当惊人! - yayitswei

2

1

def-let 的函数版本,部分功劳归于这里

(defn def-let [aVec]
  (if-not (even? (count aVec))
    aVec
    (let [aKey (atom "")       
          counter (atom 0)]
      (doseq [item aVec]
        (if (even? @counter) 
          (reset! aKey  item)           
          (intern *ns*  (symbol @aKey)  (eval item)))
        ;   (prn  item)       
    (swap! counter inc)))))

使用方法:需要用引号引用内容,例如

(def-let '[a 1 b 2 c (atom 0)])

1

对于涉及多个函数的漏洞,我喜欢使用跟踪宏来报告每个函数的调用和返回。


1

这与clojure.contrib.trace中的dotrace宏有何不同?它们似乎具有类似的目标/功能。 - intuited
区别微妙。dotrace可以深度跟踪目标函数调用的每个函数中的指定函数。eyewrap跟踪目标函数中的所有元素,并向您显示浅显结果。 - Takahiro Hozumi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接