Adam Arold
Adam Arold

Reputation: 30528

How can I debug clojure code which was created at runtime?

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

Answers (4)

mobyte
mobyte

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.

  1. REPL. You can evaluate any function or expression anytime. You can prepare environment and reproduce the situation you need to test.
  2. Immutability. Clojure provides great immutable collections and pure functions library. Also there is STM that gives you full state control of your application. You can isolate mutable parts of your program from pure functional code and make those parts as small as possible so testing code responsible for state managing becomes much easier (in common cases). Testing the pure functional part is more fun and easy.
  3. Bottom-up programming. In clojure you can write code by small pieces. You're playing with small pure functions until you can build underlying layer (library, dsl) for the next one in which you would continue this process. The testing small (pure) functions is very easy job.
  4. Logging. Obviously you can log any input parameter values at any point of code.

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

paul
paul

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

franks42
franks42

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

iced
iced

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

Related Questions