What happens if I switch environments after loading a package?

Following up from

What behavior does Julia guarantee in such a situation? I have sometimes used a similar approach during debugging/prototyping to avoid messing up the original Project.toml, but to what extent is this officially supported?

I ran into something at least related just recently. One of my projects allocates “anonymous” modules to evaluate user code, and in an attempt to not pollute their module namespace with a bunch of gensyms, I modified this to create them in a package-local module instead.

Which accidentally worked for a brief period, because I was testing it from an environment which had packages in common, but when I tried it somewhere else, I discovered that the modules have associated environments. So creating a module in PackageModule can only have using statements based on PackageModule’s environment, to get access to the same packages as the user code, the modules need to be created in the user environment.

I was surprised by this, having never thought it through, but it makes sense that since a package can only load code from its environment initially, it retains that restriction when imported into a different module, and that this property is inherited by submodules, even when created dynamically at runtime.

I realize this doesn’t actually answer what happens if you ‘spoof’ things by loading a module and then changing the environment, but it does gesture at what I would expect would happen: the code is already loaded, so it doesn’t make sense to invalidate it, but the module should now only see the switched environment.

I just checked, and Pkg.activate doesn’t have a method which takes a module. That might be a good feature to add, however, since what it does clearly acts on the current module, and it would be nice for that to generalize like it does with Base.eval.

It’s possible I’m missing something about precisely how modules and environments interact, though. Corrections and further explanations would be most welcome.

Julia has a concept of an environment stack.

https://docs.julialang.org/en/v1/manual/code-loading/#Environment-stacks

Loaded modules share a common global method table, so it’s not possible to have multiple versions of a package loaded within a single Julia process.

2 Likes