1
$\begingroup$

When working in a context, I would like all variable assignments to happen on symbols in the new context.

This doesn't normally happen. For example,

Quit[]
x=3
Begin@"mycontext`"

, then

x=4
?? x

produces a value of 4 for Global`x, rather than 3 for Global`x and 4 for mycontext`x as I would prefer in this case. This is because the Global meaning of x is used throughout (because the symbol x has appeared earlier in the Global context).

Is there any code I can add between these two blocks to make this happen? When x is referenced outside of an assignment, I would like x to be interpreted as normal.

I could indeed assign via mycontext`x=4, but what I actually want to do is to insert some context-starting/context-ending commands before/after a block of existing code, such that all variables inside the code will be treated as local, whilst avoiding the downsides of Block or Module. Namely, the downsides are that

  1. I would have to record each variable name in the first argument of Block/Module,
  2. I would no longer be able to evaluate the code line-by-line in the notebook.

Is this possible, and if so would there be any ugly side-effects?

$\endgroup$
3
  • $\begingroup$ Just prefix with a backtick. $\endgroup$
    – Alan
    Commented Feb 14, 2018 at 15:28
  • $\begingroup$ Btw, there is no magic happening here if you understand how symbols are resolved. Read carefully the documentation of $ContextPath, $Context, Begin and BeginPackage. Your problem is that although Begin changes the $Context, it does not change the current $ContextPath which is why the global x is found first if it is already defined. $\endgroup$
    – halirutan
    Commented Feb 14, 2018 at 18:49
  • $\begingroup$ Even if the mycontext` was included early on in $ContextPath, wouldn't the Global`x still be used, as mycontext`x was not defined when the expression "x=4" was interpreted? $\endgroup$ Commented Feb 14, 2018 at 21:01

2 Answers 2

1
$\begingroup$

Why not use BeginPackage/Begin? For example:

x=1;

BeginPackage["foo`"];
Begin["`Private`"];
Print[{x, Context[x]}];
End[];
EndPackage[]

{x,foo`Private`}

$\endgroup$
1
  • $\begingroup$ Thanks, this appears to do the trick. $\endgroup$ Commented Feb 14, 2018 at 17:51
1
$\begingroup$

You can prefix symbols with a backtick in order to put them in the current context.

x = 1  (* global context *)
`x = 2  (* global context *)
Begin["xxx`"]
x = 5  (* global context (because exists) *)
`x = 6  (* current context *)
End[]
x  (* 5 *)
$\endgroup$
1
  • $\begingroup$ Thanks for letting me know about that notation. I'd like to not modify the internal code itself in this case, however. $\endgroup$ Commented Feb 14, 2018 at 17:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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