Reputation: 30528
Suppose I have an application written in clojure which generates code while it is running. How can I debug that code - for which I do not have the source code?
Edit: I'm asking this question, because I was chatting about clojure with my colleague and he said that clojure programs are hard (or impossible) to test because of the reason stated above. I thought that this is a rater pessimistic approach. If it were untestable no one would've used it.
Upvotes: 2
Views: 406
Reputation: 3752
Clojure gives you so much power so you don't need debug
developing style which is common in other less powerful languages like java, c++, etc.
If you keep this programming style you will reduce the chance when you really need debugging. You can do all the job by REPL in your case. You can get input parameters of functions that generate the "debugging" dynamic code by logging . After that you would get input parameters of this dynamic code in the same way. You would have both the generated "debugging" code and input parameters at the end. So you can easily reproduce situation and test it.
Update. Regarding edited part of the question it's not correct to say that "clojure programs are hard (or impossible) to test" just because your program generates code on the fly. Keep in mind that generated code is still the data which can be manipulated as usual data collections. You don't need to build, run and freeze the whole application at the breakpoint to see what's going on there. I've already described the way you can test your dynamic code.
Upvotes: 5
Reputation: 1705
You could try making the generated code include some sort of trace using the methods from clojure/tools.trace.
E.g. if you're defining functions, you can use deftrace
instead of defn
which would then trace out calls.
From old documentation (it used to be in clojure-contrib, but as of 1.3 it's in clojure/tools.trace -- this doc's from the contrib page EDIT: link):
deftrace
Usage: (deftrace name & definition)
Use in place of defn; traces each call/return of this fn, including arguments. Nested calls to deftrace'd functions will print a tree-like structure.
There are other methods in the lib that might be handy too.
Other debugging suggestions, including where I got the info on the trace lib.
Upvotes: 1
Reputation: 1
It's a little cumbersome, but if you write your generated code into a temp-file and subsequently load&eval its content, then you will get your debug info by line number in the stacktraces.
Upvotes: 0
Reputation: 1572
Like all other code - add debug statements (like log) to the code. F10-F10-F10-style debuggers are useless for any more-less complex code anyway and shouldn't be used.
Upvotes: 0