13
$\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$
5
  • 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$ Commented Jul 31, 2015 at 12:48
  • $\begingroup$ @J. M. Disposing altogether is fine. Thanks! $\endgroup$ Commented Jul 31, 2015 at 12:50
  • $\begingroup$ There might be a cleaner/more canonical way, but it's not coming to me at the moment… :) $\endgroup$ Commented Jul 31, 2015 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
    Commented Jul 31, 2015 at 13:42
  • $\begingroup$ @Szabolcs:Thank you for the explanation! $\endgroup$ Commented Jul 31, 2015 at 13:51

3 Answers 3

19
$\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$
3
  • $\begingroup$ I think I first saw this style used by Brett Champion. $\endgroup$
    – Szabolcs
    Commented Jul 31, 2015 at 13:32
  • 2
    $\begingroup$ This is extremely useful, especially the HoldAll idea! $\endgroup$ Commented Jul 31, 2015 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
    Commented Aug 7, 2015 at 11:39
11
$\begingroup$

Seems like you are looking for Inactivate:

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

4

$\endgroup$
3
  • 3
    $\begingroup$ Ah, so that is the modern approach… :) $\endgroup$ Commented Jul 31, 2015 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
    Commented Jul 31, 2015 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
    Commented Oct 21, 2018 at 19:18
7
$\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 and acknowledge you have read our privacy policy.

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