2

Question:

How is message handling implemented in Mathematica when applying Set to unprotected global variables such as $TimeZone in the System context?

Exercise:

The documentation indicates that Set can be used with arguments such as Integer, Real, or a time zone String (e.g. "Asia/Hong_Kong"), and so if I set $TimeZone to something I know not to exist such as $TimeZone = "America/Agloe" or anything not supported for that matter, I receive the following message:

$TimeZone::tzset error message

I suspect this functionality has been implemented using a low-level or undocumented version of something similar to $Pre or its close cousin $PreRead. As these are both also global variables defined in the System context it appears this functionality is not implemented using them.

Problem Motivating the Question:

I would like to implement in one of my own packages a similar behavior for some exported global variables that will hold package settings as state variables but without having to define one or more setGlobalVariable[...] functions and avoiding protecting these global variables. This would more easily open up the possibilty to override these global variables with the Block[{$MyGlobalVariable = MySettingForGlobalVariable},...] construct.

rfrasier
  • 592
  • 3
  • 12

1 Answers1

2

With

$tz::tzset = 
  "Unable to set $tz to `1`. Time zone should be 
       an integer, real number, a string, or an Entity object.";

$tz /: Set[$tz, x_] := 
 If[Internal`PossibleTimeZoneQ[x], OwnValues[$tz] = {HoldPattern[$tz] -> x}; x, 
  Message[$tz::tzset, x, False]]

$tz = 1

$\ $1

and

$tz = "America/Agloe"

Message

$tz

$\ $1

Karsten7
  • 27,448
  • 5
  • 73
  • 134
  • How does $TimeZone avoid showing something other than {} for UpValues in the case of UpValues[$TimeZone]? – rfrasier Nov 18 '15 at 07:47
  • @rfrasier-mlp My answer only mimics the behavior of $TimeZone in a limited way. $TimeZone probably doesn't use UpVales. Try for example OwnValues[$TimeZone] = {HoldPattern[$TimeZone] -> "test"}; ?? $TimeZone and then $TimeZone; ?? $TimeZone. – Karsten7 Nov 18 '15 at 08:20
  • @rfrasier-mlp You could use Attributes[$tz] = {ReadProtected} to hide the UpValues, when ?? $tz is used. – Karsten7 Nov 18 '15 at 08:46