5
$\begingroup$

The post title's pretty much says it all...

The reminder of this post just describes the little headway I made with this problem, FWIW.


One would hope that

In[100]:= Quiet[whatever[], Messages[SomeArbitraryBuiltIn]]

would do it, but no. For one thing, Messages shows only those messages that have been defined in the current session, and (from the docs):

In[1]:= Messages[NDSolve]
Out[1]= {}

Typically, for system commands, messages are only loaded when they are required:

In[2]:= NDSolve[{x'[t] == x[t, s], x[0] == 0}, x, {t, 0, 1}];
        Messages[NDSolve]

             NDSolve::dvlen :
              The function x[t,s] does not have the same number of arguments as
              independent variables (1). >>

Out[2]= {HoldPattern[NDSolve::"dvlen"] :> 
          The function `1` does not have the same number of
            arguments as independent variables (`2`).}

Besides, even when Messages delivers the goods, it does so in a form that is not readily usable by Quiet; e.g.:

In[109]:= Take[Messages[General], 3]

Out[109]= {HoldPattern[General::appname] :> 
            The name `1` is not valid for the application. A valid name starts with 
            a letter and is followed by letters and digits., 
           HoldPattern[General::argtu] :> 
            `1` called with 1 argument; `2` or `3` arguments are expected., 
           HoldPattern[General::bktmcp] :> 
            Expression "`1`" has no closing "`2`"`4`.}

I'm sure that, after a few afternoons of torture, I'd just manage to come up with an incantation that's just ridiculous enough to get all those HoldPattern's to cooperate with Quiet (which, for additional pain, has attribute HoldAll), but I'd appreciate a leg up on that too.

$\endgroup$
0

2 Answers 2

6
$\begingroup$

Here is a way to silence all messages for a particular symbol. It requires Unprotecting Message but this has been done before, elsewhere, without major problems.

Unprotect[Message]

Message[MessageName[NDSolve, _], ___] := Null

This silences all messages for the given symbol, here NDSolve.

Since R.M apparently finds this inconvenient I'll wrap it up with a bow:

voice[sym_Symbol, Off] :=
  (Unprotect[Message];
   Message[MessageName[sym, _], ___] := Null;
   Protect[Message];)

voice[sym_Symbol, On] :=
  (Unprotect[Message];
   Message[MessageName[sym, _], ___] = .;
   Protect[Message];)

Now you just need voice[NDSolve, Off] or voice[NDSolve, On] accordingly.


Addressing the last point of your question you can do this:

heldnames = Join @@ Hold @@@ Take[Messages[General], 3][[All, 1]]
Hold[General::"appname", General::"argr", General::"argrx"]

Then use the injector pattern:

heldnames /. _[names__] :>
   Quiet[(*code*), {names}]

Or perhaps more cleanly:

heldnames = Unevaluated @@@ Take[Messages[General], 3][[All, 1]]

Quiet[(*code*), {##}] & @@ heldnames
$\endgroup$
3
  • $\begingroup$ Nulling all the messages is not a good idea because you can't easily turn it back On. $\endgroup$
    – rm -rf
    Oct 4, 2012 at 21:50
  • $\begingroup$ @rm sure you can: Message[MessageName[NDSolve, _], ___] =. If that's too long you could easily write a shorthand function. $\endgroup$
    – Mr.Wizard
    Oct 4, 2012 at 21:51
  • $\begingroup$ Well, it wasn't about inconvenience in writing it (I can wrap it in a nice function myself too), but rather that this keeps no track of messages that were generated. My initial comment was about turning a chosen message back on (which you can't with this, because you don't know what has been generated). However, I realized you can't do it with mine either (at least, not easily), even though you know which messages have been generated. $\endgroup$
    – rm -rf
    Oct 4, 2012 at 22:15
5
$\begingroup$

This is a slight variation of Mr.Wizard's answer (made community wiki because I didn't really add much). Unlike his solution, this one only locally silences the call.

ClearAll[silent];
SetAttributes[silent,HoldAll];
silent[s_Symbol[t__]]:=Internal`InheritedBlock[{Message},
  Unprotect[Message];
  Message[MessageName[s,_],___]:=Null;
  s[t]]

So you get:

silent[NDSolve[{x'[t]==x[t,s],x[0]==0},x,{t,0,1}]]
(*
==> NDSolve[{(x^\[Prime])[t]==x[t,s],x[0]==0},x,{t,0,1}]
*)

However, the silence doesn't persist:

NDSolve[{(x^\[Prime])[t]==x[t,s],x[0]==0},x,{t,0,1}]
(*
NDSolve::dvlen: The function x[t,s] does not have the same number of
    arguments as independent variables (1). >>
==> NDSolve[{(x^\[Prime])[t]==x[t,s],x[0]==0},x,{t,0,1}]
*)

And of course, it doesn't silence unrelated messages:

NDSolve[{x'[t]==x[t,s],x[0]==0/0},x,{t,0,1}]//silent
(*
Power::infy: Infinite expression 1/0 encountered. >>
Infinity::indet: Indeterminate expression 0 ComplexInfinity encountered. >>
==> NDSolve[{(x^\[Prime])[t]==x[t,s],x[0]==Indeterminate},x,{t,0,1}]
*)
$\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.