The "Updating Name" is me. I get this every now and then. Does it happen to others?
One way to have a static variable is to use "subvalues" (definitions/calls of the form h[v1, v2,...][x]
) to define methods on a data structure h[v1, v2,...]
. Here's a simplified toggler. I use an Association
for the data structure, but it could be any sort of variable. It's important to store the symbol and not its value in jk[s]
.
ClearAll[jk];
SetAttributes[jk, HoldAll]; (* must hold its arguments because s must be a Symbol in jk[s] *)
jk[] := With[{s = Unique["s"]}, s = <|"state" -> 0|>; jk[s]]; (* creates new toggler *)
jk[s_]["toggle"] := s["state"] = 1 - s["state"]; (* method to toggle state *)
jk[s_]["state"] := s["state"]; (* method to return state *)
jk1 = jk[]
jk1["state"]
(* jk[s260] the symbol s260 will be different each time *)
(* 0 *)
jk1["toggle"];
jk1["state"]
(* 1 *)
jk1["toggle"];
jk1["state"]
(* 0 *)
Since Mathematica does not have true local variables, the "static variable" is actually in the "Global`"
context:
s260
(* <|"state" -> 0|> *)
To further protect the "localization," it is common to put these such variables in a special context. One could, say, have a "jkdump
"`` context:
jk[] := With[{s = Unique["jkdump`s"]}, s = <|"state" -> 0|>; jk[s]]; (* creates new toggler *)
jk2 = jk[]
(* jk[jkdump`s13] *)
jk2["toggle"]
(* 1 *)
s13
jkdump`s13
(* s13 *)
(* <|"state" -> 1|> *)
When I tried your original code, nothing happened. Just tried it again, still nothing. But it obviously works.
When I run the code (from either my first or second post) on a fresh kernel, something happens, namely just what I showed. We must be running different things. Maybe you have a definition for test
already in your kernel session or something like that. But I can't quite reconcile "nothing happened" with "it obviously works," so maybe you mean something else.