如何调试在运行时创建的clojure代码?

时间:2013-01-14 15:35:40

标签: clojure code-generation

假设我有一个用clojure编写的应用程序,它在运行时生成代码。我该如何调试那些我没有源代码的代码?

编辑:我问这个问题,因为我和同事聊起了clojure,他说由于上述原因,clojure程序很难(或不可能)进行测试。我认为这是一种评价者的悲观态度。如果它是不可测试的,没有人会使用它。

4 个答案:

答案 0 :(得分:5)

Clojure为您提供了如此强大的功能,因此您不需要debug开发样式,这在其他功能较弱的语言(如java,c ++等)中很常见。

  1. REPL 即可。您可以随时评估任何函数或表达式。您可以准备环境并重现您需要测试的情况。
  2. 不变性即可。 Clojure提供了很好的不可变集合和纯函数库。还有STM可以让您对应用程序进行全面的状态控制。您可以将程序的可变部分与纯函数代码隔离开来,并使这些部分尽可能小,因此测试负责状态管理的代码变得更加容易(通常情况下)。测试纯功能部件更有趣,更轻松。
  3. Bottom-up programming 即可。在clojure中,您可以通过小块编写代码。您正在使用小型纯函数,直到您可以为下一个继续此过程的下一层构建底层(库,dsl)。测试小(纯)功能非常容易。
  4. 登录即可。显然,您可以在任何代码点记录任何输入参数值。
  5. 如果你保持这种编程风格,你将减少真正需要调试的机会。 在您的情况下,您可以通过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)

这有点麻烦,但如果您将生成的代码写入临时文件并随后加载并评估其内容,那么您将通过堆栈跟踪中的行号获取调试信息。