12
$\begingroup$

I have a complex program that prints out lots of diagnostic/tracing information. Is there some mechanism to evaluate it and suppress all printing? I know I could protect every Print[ ] with If[printswitch, Print[...]]. But it would be convenient if there were some way to shunt all printing to /dev/null rather than to the notebook, or its functional equivalent.

$\endgroup$
  • 2
    $\begingroup$ Do you still want the printed messages to be shunted somewhere else, or are you fine with disposing of them altogether? If it's the second, one hack-ish way would be a construction like Block[{Print = If[$verbose, Print, Identity]}, (* stuff *)]. $\endgroup$ – J. M. is away Jul 31 '15 at 12:48
  • $\begingroup$ @J. M. Disposing altogether is fine. Thanks! $\endgroup$ – Joseph O'Rourke Jul 31 '15 at 12:50
  • $\begingroup$ There might be a cleaner/more canonical way, but it's not coming to me at the moment… :) $\endgroup$ – J. M. is away Jul 31 '15 at 12:53
  • 3
    $\begingroup$ @JosephO'Rourke Block[{sym}, expr] evaluates expr with the definition of sym temporarily removed. This works even if sym is a builtin like Print. Block[{Print}, ...] makes Print behave like any undefined symbol while the body of the Block is evaluated. $\endgroup$ – Szabolcs Jul 31 '15 at 13:42
  • $\begingroup$ @Szabolcs:Thank you for the explanation! $\endgroup$ – Joseph O'Rourke Jul 31 '15 at 13:51
16
$\begingroup$

One common way to deal with diagnostic messages is something like this:

Instead of Print use some other head of your choosing, e.g. debugPrint.

f[x_] := (debugPrint["x is ", x]; x^2)

Now you can either simply define debugPrint = Print to enable messages permanently, or you can do it temporarily in a localized way with

Block[{debugPrint = Print}, f[5]]

This is both simpler to write and more flexible to manage than flags and If constructs (as in If[flag, Print[...]]).


An improvement to the technique is to set

SetAttributes[debugPrint, HoldAll]

Now when we write debugPrint[f[x]], the argument f[x] won't even be computed unless debugPrint = Print is set. This way debugPrint[ expensiveToComputeFunction[x] ] won't slow down your functions when debugging is turned off.

$\endgroup$
  • $\begingroup$ I think I first saw this style used by Brett Champion. $\endgroup$ – Szabolcs Jul 31 '15 at 13:32
  • 2
    $\begingroup$ This is extremely useful, especially the HoldAll idea! $\endgroup$ – Joseph O'Rourke Jul 31 '15 at 13:55
  • $\begingroup$ @JosephO'Rourke It seems to be used by quite a few internal functions. Try this: Block[{System`GeoGraphicsDump`geoDebugPrint = Print}, GeoGraphics[]]. $\endgroup$ – Szabolcs Aug 7 '15 at 11:39
10
$\begingroup$

Seems like you are looking for Inactivate:

ClearAll[x, y];
Inactivate[
 Print[x = 1];
 Print[y = x + 3];
 y,
 Print]

4

$\endgroup$
  • 2
    $\begingroup$ Ah, so that is the modern approach… :) $\endgroup$ – J. M. is away Jul 31 '15 at 13:21
  • 3
    $\begingroup$ Block[{modern = lazy}, yes this is the modern approach]. Block is much more powerful of course... esp. with @Szabolcs HoldAll observation $\endgroup$ – mfvonh Jul 31 '15 at 13:48
  • $\begingroup$ I don't think this works if the Prints are in an external script, as in Inactivate[<<"foo.m",Print]. $\endgroup$ – Reb.Cabin Oct 21 '18 at 19:18
4
$\begingroup$

This works for simple things

    output = $Output;
    $Output = OpenWrite["/dev/null"]; (*or "NUL" on windows *)
    Print["suppressed"];
    Close[$Output];
    $Output = output;

Not sure if it might have some unintended side effects.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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