I think the following also fits the present discussion.
Who shadows whom?
When you run
(*cleanup*)
$Context = "Global`";
Quiet@Remove["temp`*", "Global`*"];
(*--*)
Global`x = "global";
BeginPackage["temp`"];
temp`x = "temp";
The last line generates the message
...::shdw: Symbol x appears in multiple contexts {temp`,Global`}; definitions in context temp` may shadow or be shadowed by other definitions. >>
(*cleanup*)
$Context = "Global`";
Quiet@Remove["temp`*", "hemp`*", "Global`*"];
(*--*)
BeginPackage["temp`"];
temp`x = "temp";
Global`x = "global";
generates
...::shdw: Symbol x appears in multiple contexts {Global`,temp`}; definitions in context Global` may shadow or be shadowed by other definitions. >>
It looks like even the developer of this particular message was unsure about what exactly happens here ("may shadow or be shadowed").
The following would more correct in the first case:
...::shdw: Symbol x appears in multiple contexts {temp`,Global`} on the context path. Definitions in the first context, temp`, will shadow any other definitions. >>
The message should be the same in the second case, the order of the contexts should be exactly as they are in Append[$ContextPath, $Context]
.
Why is this message more correct?
A symbol x
can be defined in multiple contexts that are not on the context path just fine, the following generates no error message:
Global`x = "global";
foo`x = "foo";
bar`x = "bar";
By the way: You get no error message if you later do AppendTo[$ContextPath, "foo`"]
, even though the shadowing 'ambiguity' problem now exists.
The "::shdw" message should really be saying that within the set of contexts Append[$ContextPath, $Context]
("the context path") there exist two or more symbols with SymbolName
x
.
The original message is not clear about which definition will be given precedence, although the system knows this unambiguously: When an unqualified symbol x
appears, it will be searched in Append[$ContextPath, $Context]
in-order (it will be created in $Context
if it cannot be found).
BeginPackage
prepends the mentioned context to the context path, such that its definitions will take precedence.
"]; x = 6; {x, Global
x} which gives {6,6} ? $\endgroup$BeginPackage
to puttemp`
on the context path it works, but this demo also needs a line break:x = 5; BeginPackage["temp`"]; (*line break*) x = 6; {x, Global`x}
$\endgroup$$ContextPath
after searching$Context
, even though in reality it searches$ContextPath
before$Context
$\endgroup$