Below is a toy package that illustrates what I mean by "namespace leaks".
(* /tmp/bug_or_feature.m *)
Begin["bugOrFeature`"];
ClearAll[foo, makeFoo];
makeFoo[] := Module[{foo},
foo[] := "BUG OR FEATURE?";
foo
];
foo = makeFoo[]; (*!*)
End[];
The function bugOrFeature`makeFoo creates a function inside a Module's lexical scope, and returns it. This function (i.e. bugOrFeature`makeFoo) is used to create the function bugOrFeature`foo.
One can Get this package repeatedly, without affecting the Global` namespace:
Get["/tmp/bug_or_feature.m"]; Names["Global`*"]
(* {} *)
Get["/tmp/bug_or_feature.m"]; Names["Global`*"]
(* {} *)
This stops being the case, however, if one introduces the symbol foo in the Global` namespace:
Global`foo = 0; Names["Global`*"]
(* {foo} *)
Get["/tmp/bug_or_feature.m"]; Names["Global`*"]
(* {foo, foo$551} *)
Note that now, after evaluating the Get expression, there's an additional item in the Global` namespace, namely foo$551.
What's really troubling, however, is that Global`foo got overwritten during the last evaluation of the Get expression:
Global`foo
(* foo$551 *)
(The line marked with (*!*) in the code for /tmp/bug_or_feature.m is the culprit, AFAICT.)
What can one do to prevent code in one namespace from inadvertently overwritting symbols in another namespace?
Also,
Is the behavior illustrated above a bug or a feature?
BeginPackage– Carl Woll Mar 09 '17 at 19:57Begin["`Private`"]to createPackage`Private`foowhen theGlobal`foois screened byBeginPackage.