4
$\begingroup$

Consider the following code:

Begin["mycontext`"];
myvar = 7;
Print[Context[]];
Print[Context[myvar]];
End[];

with the output

mycontext`

mycontext`

Now consider the same code inside a Do-loop:

Do[
Begin["mycontext`"];
myvar = 7;
Print[Context[]];
Print[Context[myvar]];
End[];
, {i,1,2}];

which produces the output

mycontext`

Global`

mycontext`

Global`

What is going on here? Why is myvar considered to be in "Global`"? Even if I force the definition to

mycontext`myvar = 7;

it will still be considered to be global. How do I use contexts inside loops correctly?

The whole point of doing this is the following: I have several similar configuration files (that only contain variables) in "./folder1/config.m" and "./folder2/config.m" etc. which I have to apply some manipulations to. My idea is to loop over all folders, use a local context, Get["./folderX/config.m"], write some new values for the variables, and then Save["./folderX/config.m", "mycontext`"].

Example config.m

currentfolderstuff = 0;
anotherfolderstuff = 0;

What I want to do

Do[
(* some sophisticated stuff with many variable names that will pollute my local context *)
a = i^2 + 7^2 + ...;
b = somefunc[i];
Begin["mycontex`"];
Get["./folder"<>ToString[i]<>"/config.m"];
currentfolderstuff = a;
anotherfolderstuff = b;
Save["./folder"<>ToString[i]<>"/newconfig.m", "mycontext`"];
End[];
, {i,1,2}];
$\endgroup$
  • $\begingroup$ Where does a package have to be loaded? $\endgroup$ – Kuba Apr 10 '17 at 14:31
  • 2
    $\begingroup$ Possible duplicate of Where does a package have to be loaded? $\endgroup$ – Szabolcs Apr 10 '17 at 14:33
  • $\begingroup$ I do not full understand your update, and how these config files are related to contexts. Perhaps a explicit example will help. Get is affected by Begin because Get needs to parse the contents of a file. Regarding config files: I recommend storing config data as associations instead of code (i.e. several assignment lines). $\endgroup$ – Szabolcs Apr 10 '17 at 14:51
  • $\begingroup$ @Szabolcs: I don't have any influence in designing the config files. They are used in an external MMA program which I am trying to configurate. $\endgroup$ – image Apr 10 '17 at 15:02
  • 2
    $\begingroup$ Actually, instead of using BeginPackage, just enclose the Get in Block[{$ContextPath = {"mycontext`", "System`"}, $Context = "mycontext`"}, Get[...]]. BeginPackage does other things too which you do not want. $\endgroup$ – Szabolcs Apr 10 '17 at 15:12
8
$\begingroup$

Begin["mycontext`"] affects the parser, not the evaluator.

These are separate expressions:

Begin["mycontext`"];
myvar = 7;
Print[Context[]];
Print[Context[myvar]];
End[];

They get parsed and evaluated one by one. Once Begin["mycontext`"]; is evaluated, the new context applies to all subsequent lines.

This is a single expression:

Do[
Begin["mycontext`"];
myvar = 7;
Print[Context[]];
Print[Context[myvar]];
End[];
, {i,1,2}];

It gets parsed as one unit, an evaluation begins only afterwards. Begin["mycontext`"]; does not get a chance to get evaluated before the parsing of myvar.

$\endgroup$
  • $\begingroup$ Ok, so how do I fix that? How do I force MMA to evaluate Begin[] inside a loop separately? $\endgroup$ – image Apr 10 '17 at 14:37
  • 1
    $\begingroup$ @Marcel In most cases trying to do this is a bad idea. Begin does not belong in a loop. Can you explain in clear terms why you want to do it? (Please edit the question instead of explaining in a comment.) $\endgroup$ – Szabolcs Apr 10 '17 at 14:38
  • 1
    $\begingroup$ @Marcel please show a line or two from your config files so that everything is clear. Since the context does not change you can begin it before calling Do and close after. $\endgroup$ – Kuba Apr 10 '17 at 14:51
  • $\begingroup$ @Kuba: Ok, I have done that. $\endgroup$ – image Apr 10 '17 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.