4
$\begingroup$

I have some package code that does rather complex multi-context evaluation, and I know it's going to throw warnings about shadowed symbols. The shadowing isn't actually a problem. For the end-user's sake, I want to suppress these warnings.

Quiet can suppress all messages, which is too heavy-handed. Other kinds of messages might be important and should be reported.

Quiet can also suppress specific named messages, which is too precise. I don't want to name the specific symbols that might be shadowed, for two reasons: I can't necessarily predict them, and naming the symbols explicitly adds their names to a context that only exacerbates the shadowing problem.

What I would really like to do is to call Quiet[stuffToEvaluate,{*::shdw}] in order to suppress the shadowing message for any symbol, but Mathematica doesn't seem to accept a wildcard there. None of the message groups listed in $MessageGroups is helpful, either.

Any suggestions, o sages?

$\endgroup$
3
  • 1
    $\begingroup$ Can't you just avoid the shadowing? The shadowing issues typically indicate the problems with design of the code, and can be avoided. OTOH, these problems, if not taken care of, can lead to pretty nasty surprises, so I'd hesitate to just silence them. $\endgroup$ Aug 29, 2015 at 22:24
  • 7
    $\begingroup$ There's Off and On with General::shdw, which might work; but I second Leonid's concerns. $\endgroup$
    – Michael E2
    Aug 29, 2015 at 22:43
  • $\begingroup$ I hear you, but trying to get rid of the shadowing warnings has been something like playing whack-a-mole; getting my code to work AT ALL in Mathematica's messed-up namespace system has been a nightmare. Long term, I'm going to try using a sandboxed sub-process with LinkCreate to avoid these problems, but that will take some time to figure out and my students need a new assignment yesterday. $\endgroup$
    – ibeatty
    Aug 30, 2015 at 0:42

1 Answer 1

10
$\begingroup$

Michael's suggestion to use Off and On with General::shdw will be one solution to your problem - if you really decide to go down this road (which is what we recommended against in comments). But, just for the record, it is not difficult to implement one's own version of Quiet, that would be more selective.

Here is one possible implementation:

ClearAll[selectiveQuiet];
selectiveQuiet[symPattern_, msgPattern_] :=
  Function[
    code
    ,
    Internal`InheritedBlock[{Message},
      Module[{inMsg, quiet},
        Block[{quiet},
          SetAttributes[quiet, HoldAll];
          quiet[Verbatim[MessageName][symPattern, msgPattern], ___] :=
             Function[c, Null, HoldAll];
          quiet[x_, ___] := # &;
          Unprotect[Message];
          (call : Message[args___]) /; ! TrueQ[inMsg] :=
            Block[{inMsg = True},
              quiet[args][call]
            ];
          Protect[Message];
          code
        ]]]
    ,
    HoldAll
  ];

In your case, you would use it as

selectiveQuiet[_, "shdw"][your-code]

But the function selectiveQuiet is much more general, of course. For example:

selectiveQuiet[Part, _][Range[5][[10]]]

(* {1, 2, 3, 4, 5}[[10]] *)

Note that there are subtle but important differences between Quiet and selectiveQuiet. Basically, while Quiet silences messages, selectiveQuiet suppresses them entirely. In particular, Check behaves differently when used inside Quiet or selectiveQuiet:

selectiveQuiet[Power, _][Check[1/0, $Failed]]

(* ComplexInfinity *)

while

Quiet @ Check[1/0, $Failed] 

(* $Failed *)

For the case at hand, selectiveQuiet may have advantages over On -Off method, because it doesn't redefine the global state - the behavior of Message is only changed for the code you run inside of selectiveQuiet, and there is no danger to affect any other code or forget to set the messages On again.

$\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.