Let's say I have file named test.m
containing
test[arg1_] := ( Print[arg1];)
What is the best technique for calling test like test["value"]
while preventing test from being added to the $ContextPath
?
The following almost works except you must know function values ahead of time
Block[{$ContextPath,test}, Needs["test`"];test["test"]];
My question is: How do I generalize the call above to work with any number of functions without the user needing to input definitions manually?
Answer
As Nasser notes in a comment every Symbol has a context. You should be aware that Symbols are created during parsing. See: Local variables in Module leak into the Global context.
Alright, now that we worked out what you want here is the simplified answer:
We can perform a similar operation to BeginPackage
with Block:
Block[{$ContextPath = {"runPrv`", "System`"}, $Context = "runPrv`"}, . . .]
We can combine this with Leonid's method from Is it possible to use Begin and End inside a Manipulate? to keep contexts from being fully resolved until we are ready for evaluation inside the Block
. (Note that Global`
Symbols are still created, as discussed above, but they will not be defined.) I believe "runPrv`"
may be left out of $ContextPath
in our application so long as we don't change the $Context
from "runPrv`"
within the Block itself. Finally we have:
SetAttributes[runPrivate, HoldAllComplete];
runPrivate[code_] :=
With[{body = MakeBoxes @ code},
Block[{$ContextPath = {"System`"}, $Context = "runPrv`"},
ToExpression @ body]]
Now:
runPrivate[
Get["test.m"];
a = 5;
test[a]
]
5
Global Symbols a
and test
remain undefined:
?a
?test
Global`a
Global`test
Comments
Post a Comment