Cause
The problem is due to a bug involving Catch
and init.m
that occurs in (at least) Mathematica versions 7, 8 and 9. It has been reported to Wolfram Support and they have acknowledged it as a bug. At time of writing, WRI has offered neither diagnosis nor workaround for this problem.
Reproduction Steps and Analysis
To reproduce the issue, place the following expression in the init.m
file and then restart the session:
$result = StringMatchQ["name", "noMatch" | "name"];
The message window will show two instances of the message Throw::nocatch: Uncaught Throw[False] returned to top level. Furthermore, StringMatchQ
no longer functions correctly in the new session:
$result
(* False *)
StringMatchQ["name", "noMatch" | "name"]
(* False *)
This second result is extremely disturbing since it means that all evaluations in the new session that could potentially involve StringMatchQ
must be treated with suspicion (and who knows what else is suspect as well). The good news is that occurrence of this problem must be extremely rare because it has gone unnoticed since at least 2008.
Judicious use of Trace
and similar debugging tools reveals that it is possible to produce the exhibited error messages using a simpler form:
Catch[Throw[False]]
However, this simpler form does not corrupt the behaviour of StringMatchQ
.
Catch
is relevant to the current matter at hand because StringMatchQ
calls StringPattern`PatternConvert
, which in turn calls StringPattern`Dump`rule1b
. This last has the following replacement rule (in outline):
(List|Alternatives)[a__] :>
If[Catch[(If[!SingleCharacterQ[#1],Throw[False]]&) /@ {a};True], ...]
This rule is applicable to the exhibited troublesome expression because it involves the use of Alternatives
, and a Throw
occurs because the strings are longer than single characters:
StringMatchQ["name", "noMatch" | "name"];
Workaround
Experimentation reveals a workaround, for versions 8 and 9 at least. Catch
and StringMatchQ
will operate properly if run as an immediate scheduled task instead of directly inline. For example, we can place the following lines in the init.m
file:
RunScheduledTask[
$result = StringMatchQ["name", "noMatch" | "name"]
; RemoveScheduledTask @ $ScheduledTask
, {0}
]
The resulting session functions properly:
$result
(* True *)
StringMatchQ["name", "noMatch" | "name"]
(* True *)
Apparently, the scheduled task environment is isolated from whatever causes this problem.
I cannot stress enough that this is an empirical result with neither proper explanatory backing nor WRI endorsement.
StringMatchQ["name", "noMatch" | "name"]
returnsFalse
in a new notebook if it's in init.m. If I change"noMatch"
to something like"foo"
it returnsTrue
. When I take it out of init.m and restart Mathematica, it returnsTrue
. Seems like a bug somewhere... $\endgroup$init.m
files I have no idea, can't dig deeper at the moment. It could be for example that it relies on Java and Java is not yet available, or may be something else of a similar nature. $\endgroup$Throw
. Nice finding. $\endgroup$Catch
doesn't work properly in theinit.m
file. I get the exhibited error message if I putCatch[Throw[False]]
in my init file using V7, V8 or V9. In the example at hand, aCatch
is used inStringPattern`Dump`rule1b
(called byStringPattern`PatternConvert
called byStringMatchQ
). $\endgroup$Catch
failing. It looked likeCatch
is tied to a particular stack, and in some cases it looks like evaluation is using different stacks for parts of it. I may have just given a wrong explanation, but this is what it looked like. I did not have the time to dig deeper and obtain a fully satisfactory answer for these cases. $\endgroup$