May be someone can explain why I can't use Begin["context`"]
and End[]
inside a Manipulate
expression, or inside the initialization section?
When I use it in the Manipulate
expression, and close the notebook and restart, I get the error:
Here is the code, please feel free to modify as needed. I am just trying to see if the idea of different contexts can be used inside Manipulate. It is just not seeing obj`f[]
at all.
Manipulate[
Begin["obj`"];
f[y_] := y^2 + 1;
End[];
{x, Date[], obj`f[1]},
{{x, 0, "x"}, 0, 10, 1, Appearance -> "Labeled"},
TrackedSymbols :> {x}
]
I also tried in the initialization section, same problem. I think this is because Manipulate
itself is a Dynamic
module, it does not like new context created inside it?
This is a snapshot of the above:
DynamicModule[{x = 5},
Begin["obj`"];
f[y_] := y^2 + 1;
End[];
{x, Date[], obj`f[1]}
]
Outside Manipulate
, it works fine of course: (restating kernel helps before running this below again after the above just in case)
Begin["obj`"];
f[y_] := y^2 + 1;
End[];
obj`f[2]
gives 5
Answer
Short answer: yes, it is possible.
The problem is that parsing is done line-by-line only for the top-level code. For code inside some head(s), it is first parsed as a whole. Therefore, your f
is parsed to Global`f
, and this is why that symbol is used. Here is what you can do, schematically:
DynamicModule[{x = 5},
With[{def = MakeBoxes[f[y_] := y^2 + 1;], ff = MakeBoxes[f]},
Block[{$ContextPath},
BeginPackage["obj`"];
ReleaseHold[MakeExpression@ff];
Begin["`Private`"];
ReleaseHold[MakeExpression@def];
End[];
EndPackage[]]
];
{x, Date[], obj`f[1]}]
What we do here is to delay the parsing (or, more precisely, the last stage of it) of our definition until run-time, converting it first to boxes and thus preventing its premature parsing. I used a similar technique in my answer in this thread. We could have converted to strings, but I prefer boxes as being still "on this side of Mathematica".
Note that a side effect of this code is that a symbol f
is still created in the context which is current when the code executes (Global`
here). If you want to avoid that, you could insert Remove[f]
before Block
. I went all the way to use `Private`
sub-context, to avoid polluting the current context with some auxiliary symbols created during assignments.
You can also automate this code with some meta-programming.
Comments
Post a Comment