Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want hide all outputs created by Print command from user's function defined in module .m.

More precisely the problem is following:

I have a module that solves some specific task (It's not necessary to know the task for understanding the question). I use Print command inside the module to output process of evaluation. It's useful for debugging but not for using (all inner output must be hidden when user calls a function declared in the module).

So, in every stable version of the module I have to put comments (* *) and delete them for gebugging. I suppose that this way is uncivilized, and Mathematica should have a regular way to hide inner outputs.

For example, we have 3 files in the same directory. Can you suggest me a simple way how to hide all outputs by default and print all outputs in debugging mode?

modul.m:

f[x_]:=Module[{y}, y=Cos[x]*Sin[x];
Print["modul.m: y=",y];
Return[y]];

debugging.nb:

SetDirectory[NotebookDirectory[]];
<< modul.m;
x=10;
f[x] (* print all inner output generated while f is evaluating*)
x=20;
f[x](* print all inner output generated while f is evaluating*)

application.nb:

<< modul.m
y=f[10]+f[20];
(* Hide all outputs of f during evaluation. Command ; doesn't work for this issue. *) 
share|improve this question

1 Answer 1

up vote 4 down vote accepted

The short answer to this is that a simple Print[] is not a good way to debug a large package. It is not possible to turn it off (in a robust way) only for your package, but not in other places (it can be disabled globally, the simplest way being Print; Unprotect[Print]; Print = Null &, but this will severely annoy your users)

For much better ways to emit debug messages, and turn them off, see here:

http://stackoverflow.com/questions/8698754/message-generation-in-mathematica

I'll summarize Brett Champion and my own answers from there, as personally (and subjectively) I consider those the best solutions, but please read the full thread there.


Brett Champion's answer:

Use a custom symbol for debug messages(just like your package functions, you may want to put it in a separate context to avoid collisions), like this:

...
debugPrint[expr]
...

Then define a PrintDebug function like this:

Attributes[PrintDebug]={HoldAll}

PrintDebug[expr_] := Block[{debugPrint = Print}, expr]

Any code wrapped in PrintDebug will print messages. If there's no PrintDebug wrapper, message printing is disabled.

MyFunction[1,2,3] // PrintDebug

Alternately you may set a value to debugPrint globally to enable message printing for everything or just do $Pre = PrintDebug.


My answer:

We can use the built-in Message functionality for debugging too:

debugPrint::msg = "Debug message: `1`";    
debugPrint[msg_] := Message[debugPrint::msg, msg]

Use the function like this:

debugPrint["hello"]

Turn off or on messages like this:

Off[debugPrint::msg]

On[debugPrint::msg]
share|improve this answer
    
Thank you very much for your answer! I chose first solution (by Brett Champion's) since it can work with multiple argument in debugPrint debugPrint["modul.m: y=", y];debugPrint["modul.m: y=", y,"z=",z]; But the idea of using Message looks great. I wish there was posibility to define debugPrint with apriory unknown number of arguments. –  Anonimous Jan 11 '12 at 7:37
    
@Anonimous When using the Message version of debugPrint, you can either put everything in a list before you pass it to it, debugPrint[{1,2,3}], or we could do something like debugPrint[args__] := Message[debugPrint::msg, StringJoin[ToString /@ {args}]] to emulate Print (unlike Print, this loses formatting, so you can't use it with e.g. Graphics!), or debugPrint[args__] := Message[debugPrint::msg, StringJoin[Riffle[ToString /@ {args}, ", "]]] to have comma separated arguments. Preserving formatting is also possible, but it's more advanced so I won't go into it. –  Szabolcs Jan 11 '12 at 7:58
    
@Anonimous I just realized that StringForm is nestable, so you could use the message based debugPrint like this too: debugPrint[StringForm["x = ``, y = ``", x, y]] (or maybe integrate StringForm directly into the function) –  Szabolcs Jan 11 '12 at 23:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.