Using Context as a scoping construct in Mathematica
Thinking about a solution to my previous question about switching between numerical and analytical "modes" in a large Mathematica project, I thought about the idea of using Context
as a scoping construct.
The basic idea is to make all numerical value assignments in their own context, e.g.
Begin["Global`Numerical`"]
par1 = 1;
par2 = 2;
...
End[]
and have all the complicated analytical functions, matrices, etc. in the Global context.
Ideally I would be able to work in the Global context and 开发者_开发知识库switch to everything being numeric with a simple Begin[Global'Numeric']
and switch back with End[]
.
Unfortunately this doen not work, since e.g. f[par1_,par2_,...] := foo
defined in the Global context will not use par1
, par2
, etc which have been defined in a sub context of Global.
Is there a way to make sub contexts inherit definitions from their parent context? Is there some other way to use contexts to create a simple switchable scope?
Well, here's one way to get around (what I think) is your problem by adjusting $ContextPath
appropriately:
SetOptions[EvaluationNotebook[], CellContext -> "GlobalTestCtxt`"];
Remove[f, GlobalTestCtxt`Numerical`f, par1, par2];
f[par1_, par2_] := {par1, par2};
savedContextPath = $ContextPath;
Begin["GlobalTestCtxt`Numerical`"];
Print[{$ContextPath, $Context}];
$ContextPath = DeleteCases[$ContextPath, "GlobalTestCtxt`"];
par1 = 1;
par2 = 2;
End[];
$ContextPath = savedContextPath;
Now, this will evaluate analytically:
f[par1, par2]
And this numerically:
savedContextPath = $ContextPath;
Begin["GlobalTestCtxt`Numerical`"];
$ContextPath = Prepend[$ContextPath, $Context];
f[par1, par2]
End[];
$ContextPath = savedContextPath;
The reason I say it's fragile is that unless you are careful, it's easy to get the symbol into the wrong context. For instance, suppose you forgot to evaluate f in the global context before evaluating the "numerical" block. Well, now your numerical block will not work simply because it'll turn to a (perfectly valid) symbol GlobalTestCtxt`Numerical`f
, which you have inadvertently entered into the symbol table when you first evaluated the numerical block. Because of potential bugs like this, I personally don't use this approach.
Edit: fixed a bug (it is necessary to hide the "Global" context when doing assignments in numerical context)
精彩评论