Skip to main content
Fixed a lot of ticks
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test``test` , however in the first case, we initially evaluate the CompoundExpression which means we put Global``xGlobal`x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global``x=42Global`x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System``System` context in order to avoid scoping for example Sin to test``Sintest`Sin:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Block[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global``xGlobal`x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global``xGlobal`x and not to test``xtest`x as would normally be expected if you had done a line by line evaluation of the context switching.

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test`` , however in the first case, we initially evaluate the CompoundExpression which means we put Global``x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global``x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System`` context in order to avoid scoping for example Sin to test``Sin:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Block[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global``x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global``x and not to test``x as would normally be expected if you had done a line by line evaluation of the context switching.

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test` , however in the first case, we initially evaluate the CompoundExpression which means we put Global`x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global`x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System` context in order to avoid scoping for example Sin to test`Sin:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Block[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global`x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global`x and not to test`x as would normally be expected if you had done a line by line evaluation of the context switching.

Slight code cleanup
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test`` , however in the first case, we initially evaluate the CompoundExpression which means we put Global``x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global``x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System`` context in order to avoid scoping for example Sin to test``Sin:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Module[Block[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held, StandardForm]]ToExpression[held]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global``x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global``x and not to test``x as would normally be expected if you had done a line by line evaluation of the context switching.

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test`` , however in the first case, we initially evaluate the CompoundExpression which means we put Global``x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global``x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System`` context in order to avoid scoping for example Sin to test``Sin:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Module[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held, StandardForm]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global``x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global``x and not to test``x as would normally be expected if you had done a line by line evaluation of the context switching.

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test`` , however in the first case, we initially evaluate the CompoundExpression which means we put Global``x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global``x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System`` context in order to avoid scoping for example Sin to test``Sin:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Block[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global``x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global``x and not to test``x as would normally be expected if you had done a line by line evaluation of the context switching.

added 1 characters in body
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test`` , however in the first case, we initially evaluate the CompoundExpression which means we put Global``x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global``x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System``` context in order to avoid scoping for exampleSystem`` Sin context in order to avoid scoping for example toSintest``Sin` to test``Sin:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Module[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held, StandardForm]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global``x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global``x and not to test``x as would normally be expected if you had done a line by line evaluation of the context switching.

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test`` , however in the first case, we initially evaluate the CompoundExpression which means we put Global``x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global``x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System``` context in order to avoid scoping for example Sintotest``Sin`:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Module[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held, StandardForm]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global``x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global``x and not to test``x as would normally be expected if you had done a line by line evaluation of the context switching.

I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:

Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x} 
)

{42,test`x}

Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}

{x,42}

If you use Trace You will see that in the second example everything is evaluated line-by-line, which means that when we get to x=42 the active context is test`` , however in the first case, we initially evaluate the CompoundExpression which means we put Global``x into scope, which means we already have an x defined when we evaluate x=42 thus it's interpreted as Global``x=42.

A way to get around this is to use the fact that MakeBoxes will automatically remove any context currently in $ContextPath while ToExpression Automatically puts any symbol not found in any context into $Context. Here I exclude the System`` context in order to avoid scoping for example Sin to test``Sin:

SetAttributes[ContextScope, HoldAll]
ContextScope[context_, expression_, exclude_: {"System`"}] :=
Module[{held},
 Block[{$ContextPath = Complement[$ContextPath, {"System`"}]}, held = MakeBoxes[expression]];
 Block[{$Context = context, $ContextPath = {context}}, 
 ToExpression[held, StandardForm]]
]

ContextScope["test`", x = Sin[0]]
{x, test`x}

{x,0}

This will however still put Global``x in scope, it simply does not assing a value to it. So any new call to x=somethign will assign a value to Global``x and not to test``x as would normally be expected if you had done a line by line evaluation of the context switching.

added 39 characters in body
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76
Loading
added 287 characters in body
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76
Loading
added 287 characters in body
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76
Loading
Corrected incorrect conclusion
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76
Loading
edited body
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76
Loading
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76
Loading