2013-01-14 33 views
2

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

编辑:我在问这个问题,因为我和我的同事聊过clojure,他说因为上述原因,clojure程序很难(或不可能)测试。我认为这是一个评价者悲观的做法。如果这是无法测试的,没有人会使用它。

回答

5

的Clojure给你这么大的权力,所以你不需要debug开发风格,是常见于其他不那么强大的语言,如JAVA,C++等

  1. REPL。您可以随时评估任何函数或表达式。您可以准备环境并重现您需要测试的情况。
  2. 不变性。 Clojure提供了很好的不可变集合和纯函数库。还有STM可以让你完全控制你的应用程序。您可以将程序的可变部分与纯函数代码隔离开来,并尽可能小地使这些部分尽可能小,以便测试负责状态管理的代码变得更容易(通常情况下)。测试纯功能部件更加有趣和简单。
  3. Bottom-up programming。在clojure中,你可以用小块代码编写代码。你正在玩小的纯函数,直到你可以为下一个构建底层(库,dsl),你将继续这个过程。测试小(纯)功能是非常容易的工作。
  4. 伐木。显然你可以在任何代码点记录任何输入参数值。

如果您保持这种编程风格,您将减少真正需要调试的机会。 您可以在您的案例中由REPL完成所有工作。您可以通过记录获取生成“调试”动态代码的函数的输入参数。之后,您将以相同的方式获取此动态代码的输入参数。您最终会同时生成“调试”代码和输入参数。因此,您可以轻松再现情况并对其进行测试。

更新。关于问题的编辑部分,说“clojure程序很难(或不可能)测试”是正确的,只是因为你的程序在运行中生成代码。请记住,生成的代码仍然是可以像平常一样收集数据的数据。您不需要在断点处构建,运行和冻结整个应用程序以查看发生了什么。我已经描述了你可以测试你的动态代码的方式。

0

像所有其他代码一样 - 向代码中添加调试语句(如日志)。无论如何,F10-F10-F10风格的调试器对于任何更复杂的代码都是无用的,因此不应该使用。

+0

如果使用Eclipse不可能做一些调试吗? – octopusgrabbus

+1

您无法使用“经典”调试器来调试_any_复杂的应用程序,因为它通常涉及数千个线程,运行时代码生成以及不可用的代码。 – iced

0

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

0

您可以尝试使用clojure/tools.trace中的方法使生成的代码包含某种跟踪。

E.g.如果您正在定义功能,则可以使用deftrace而不是defn,然后它会跟踪呼叫。

从旧的文档(它使用的是用Clojure-contrib请,但由于1.3是用Clojure/tools.trace - 这个文档的于contrib页面编辑:link):

deftrace

用法:(deftrace名&定义)代替DEFN的

使用;跟踪此fn的每个调用/返回,包括 参数。嵌套调用deftrace的函数将打印一个类似于树状结构的 。

在lib中还有其他方法可能也很方便。

Other debugging suggestions, including where I got the info on the trace lib.

相关问题