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