Automatically add debug contents to a program
In your example, a message is issued at the problem. You want to find out where the message comes from. The debugger is pretty good at this. Just enable the debugger, then enable Break at Messages, then evaluate your code.
You get a nice display of the stack, which in itself allows you to localize the problem.
Since this was an interactive evaluation, the problem is also highlighted in the notebook
If we had a
Module
there, we could see its local variables in the Stack window, with their values.Evaluation is suspended in you're in a dialog. You can evaluate things and examine the kernel state. Evaluating
i
gives1
(even thoughi
is a local variable.You could even put
Dynamic[i]
in a new windows and watchi
change live as you step through the code.
In my opinion, I think the debugger is way underrated. The big problem with it is that it has a breakpoints feature, like traditional debuggers, and people try to use this then get frustrated. There are many reasons why breakpoints just don't fit Mathematica well. Don't use them. The other features work well.
When I do need a breakpoint, I explicitly insert an Assert[False]
in the code and enable Break at Asserts.
I know this does not answer your actual question, but I hope you will still find it useful to solve your problem ...
Actually form C.E.'s comment.
Make a custom function for this
SetAttributes[AddPrint, HoldFirst]
AddPrint[loopBody_] :=
Module[{st = ToString[Unevaluated[loopBody], InputForm], i = 0},
StringReplace[st,
RegularExpression["^|(?<=;)"] :> TemplateApply["Print[``];", ++i]]]
It can help you add Print
into your loopBody
automatically
loopBody = AddPrint[j = i^2; a + b; Thread[{{1}, {2, 3}}]]
Print[1];j = i^2;Print[2]; a + b;Print[3]; Thread[{{1}, {2, 3}}]
I often use the form
Block[{Print=Identity}, expr]
to suppress Print
statements that I have added for debug purposes.