Another resource related to this question is the tutorial
How Modules Work
It explains how, as others have pointed out, the symbol that is actually created in
Module[{x}, x]
is x$nnn
, where nnn
is the current value of $ModuleNumber
. $ModuleNumber
is increased whenever Module
is called (with local variables) and at other times.
There has been some curiosity about whether one can get at the local variable using ToExpression
. One can take advantage of $ModuleNumber
to do this, but it is hard to imagine it would be worth working around the difficulties. In every case, I would think it should be possible to avoid having to do this with little inconvenience.
So just to satisfy curiosity here is a way:
MainVar = 1;
Carrier = "MainVar";
f[] := Module[{MainVar},
MainVar = 3;
ToExpression[Carrier <> "$" <> ToString[$ModuleNumber - 1]]]
f[]
(* 3 *)
You have to subtract 1
from $ModuleNumber
because it gets increased right after the variable(s) (only MainVar
in this case) are instantiated.
But here's where it gets tricky. You have to make sure that $ModuleNumber
hasn't been increased when you use it. Many internal functions use Module
. For instance, consider this:
MainVar = 1;
Carrier = "MainVar";
f[] := Module[{MainVar},
Print[SymbolName@Unevaluated@MainVar];
Print[$ModuleNumber];
MainVar = Integrate[x^2, {x, 0, 1}];
Print[$ModuleNumber];
ToExpression[Carrier <> "$" <> ToString[$ModuleNumber - 1]]]
f[]
(*
Print: MainVar$328200
328201
328218
Out[]= MainVar$328217
*)
One way to work with it is to store the current module number at the start:
MainVar = 1;
Carrier = "MainVar";
f[] := Module[{MainVar, myModuleNumber = $ModuleNumber},
Print[myModuleNumber];
Print[$ModuleNumber];
MainVar = Integrate[x^2, {x, 0, 1}];
Print[$ModuleNumber];
ToExpression[Carrier <> "$" <> ToString[myModuleNumber]]]
f[]
(*
Print: 328221
328222
328229
Out[]= 1/3
*)
MainVar
symbol "true name" isn't mainVar. Try removing the assignmentMainVar = 3;
to see it. $\endgroup$Print[SymbolName@Unevaluated@MainVar]
inside the module to see what the real local name ofMainVar
is insideModule
. $\endgroup$Module
, Mathematica still uses the global one instead of the local one? I'm confused especially becausePrint[MainVar]
uses the local one. $\endgroup$Module
. Might be fun to think about but I can't seem to find one method that would work. $\endgroup$