假设我有一个用clojure编写的应用程序,它在运行时生成代码。我该如何调试那些我没有源代码的代码?
编辑:我问这个问题,因为我和同事聊起了clojure,他说由于上述原因,clojure程序很难(或不可能)进行测试。我认为这是一种评价者的悲观态度。如果它是不可测试的,没有人会使用它。
答案 0 :(得分:5)
Clojure为您提供了如此强大的功能,因此您不需要debug
开发样式,这在其他功能较弱的语言(如java,c ++等)中很常见。
如果你保持这种编程风格,你将减少真正需要调试的机会。 在您的情况下,您可以通过REPL完成所有工作。您可以通过记录获取生成“调试”动态代码的函数的输入参数。之后,您将以相同的方式获得此动态代码的输入参数。您将在最后生成“调试”代码和输入参数。因此,您可以轻松地重现情况并进行测试。
<强>更新即可。关于问题的编辑部分,仅仅因为你的程序在运行中生成代码,“clojure程序很难(或不可能)测试”是不正确的。请记住,生成的代码仍然是可以像通常的数据集合一样操作的数据。您不需要在断点处构建,运行和冻结整个应用程序以查看其中发生的情况。我已经描述了测试动态代码的方式。
答案 1 :(得分:1)
您可以尝试使用clojure/tools.trace中的方法使生成的代码包含某种跟踪。
E.g。如果您要定义功能,则可以使用deftrace
代替defn
,然后跟踪调用。
从旧文档(它曾经是clojure-contrib,但从1.3开始,它在clojure / tools.trace中 - 这个文档来自contrib页面编辑: link) :
deftrace
用法:( deftrace name&amp; definition)
代替定义使用;追踪每个fn的调用/返回,包括 参数。嵌套调用deftrace'd函数将打印出来 树状结构。
lib中还有其他方法可能也很方便。
Other debugging suggestions, including where I got the info on the trace lib.
答案 2 :(得分:0)
与所有其他代码一样 - 将调试语句(如日志)添加到代码中。无论如何,F10-F10-F10型调试器对于任何更复杂的代码都是无用的,不应该使用。
答案 3 :(得分:0)
这有点麻烦,但如果您将生成的代码写入临时文件并随后加载并评估其内容,那么您将通过堆栈跟踪中的行号获取调试信息。