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.
BeginPackageto 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}– Chris Degnen Mar 08 '14 at 12:21$ContextPathafter searching$Context, even though in reality it searches$ContextPathbefore$Context– Szabolcs Mar 08 '14 at 13:48$ContextPath, because this list of contexts should be searched after the symbol cannot be found in$Context. SinceBeginresets the current context, the behaviour is surprising and in the book, the results are different. – halirutan Apr 07 '15 at 22:42