16

Is there a way to find an existing error message in the System` context, that is used for a certain case? I want to include a message in a custom function that compares all the arguments of the function, and checks if they have the same length. I'm pretty sure that there is one such, but I can't seem to find it. And I don't want to insert new symbols or messages to the namespace if I can use existing ones. Now I am looking for a method that is general; i.e., it can be applied to other cases, not just this one with argument lengths.

For example I am looking for a message that works like this:

General::badlen = "The length of arguments `1`, `2`, `3` must be the same.";

myFun[x_List, y_List, z_List] /; 
  If[Length@x == Length@y == Length@z, True,
     Message[myFun::badlen, x, y, z]; False] := x*y*z;
J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
István Zachar
  • 47,032
  • 20
  • 143
  • 291
  • 1
    The nearest message that I am aware of is General::bldim... anyway, you might want to look for appropriate messages that you can use within Messages.m, which is in the directory $InstallationDirectory <> "/SystemFiles/Kernel/TextResources/English". – J. M.'s missing motivation Nov 17 '12 at 11:46
  • Thanks @J.M. It could be a perfect answer... – István Zachar Nov 17 '12 at 12:38
  • I don't think it's a completely optimal message, tho. You'll of course need to inscribe additional code to determine which two of the three arguments given have the incompatibility... also, there might be a better error message within Messages.m; I just got lazy after five minutes. – J. M.'s missing motivation Nov 17 '12 at 12:43
  • @J.M. Well, my Q is not about this specific error message (it could have been any other task), but the way how to access/query/find built-in error messages. – István Zachar Nov 17 '12 at 12:58

2 Answers2

18

Here's a tiny utility function you might use if you're trying to look for a message that contains a known string:

searchMessages[str_String, opts___] := 
      Sort[Select[Flatten[Map[ToExpression[#, InputForm, Defer] :>
                              Evaluate[ToExpression[#]] &,
           StringCases[FindList[FileNameJoin[{$InstallationDirectory, "SystemFiles",
                                              "Kernel", "TextResources", "English",
                                              "Messages.m"}], str, opts,
                                IgnoreCase -> True],
                       RegularExpression["([\\w$]|`)+::(\\w)+"]], {2}]],
                  With[{s = Last[#]},
                       StringQ[s] && ! StringFreeQ[s, str, IgnoreCase -> True]] &]]

For example,

searchMessages["determinant"]
   {TransferFunctionModel::method :> 
    "Value of option Method -> `1` is not Automatic, \"DeterminantExpansion\",
     \"ResolventIdentities\", \"Inverse\", or Generic."}

The function tries to search for apropos messages within the Messages.m file within the system files. It won't always find an appropriate message, since there are messages like General::offline that aren't within Messages.m (though grep tells me that that particular message is in $InstallationDirectory <> "SystemFiles/Autoload/PacletManager/Kernel/Services.m", so you know what to modify). Still, it's a start...

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
6

We can scan the messages that have been loaded into the current session like this:

messages[pattern_, context_:"*"] :=
  Cases[
    Quiet[ToExpression[#, InputForm, Messages]& /@ Names[context~~"*"], General::readp]
  , (_[n_] :> m_String) /; !StringFreeQ[m, pattern, IgnoreCase -> True] :> HoldForm@n :> m
  , {2}
  ]

messages["arguments", "System`"]
(*
{General::bldim:>The arguments `1` and `2` in `3` do not have compatible dimensions.}
*)

messages["longer"]
(*
{General::partd:>Part specification `1` is longer than depth of object.,
 Part::partd:>Part specification `1` is longer than depth of object.}
*)

The emphasis here is on loaded messages. This method will not find any messages in packages that have not yet been loaded. Also beware that some packages load symbols (and their messages) lazily, on demand.

WReach
  • 68,832
  • 4
  • 164
  • 269