While writing the documentation of a package I’m currently developing, I did ran into a problem with Documenter.jl which I could track down to the sandboxing mechanism of Documenter in combination with Core.eval.
Without explaining the context here the MWE:
This code works:
function bar()
Main.Sandbox.Foo()
end
module Sandbox
struct Foo end
Main.bar()
end
But when you call the Main.bar() via Core.eval you get an “Sandbox is not defined message”:
function bar()
Main.Sandbox.Foo()
end
expr = Meta.parseall("""
struct Foo end
Main.bar()
""")
Core.eval(Module(:Sandbox), expr)
If the code is evaluated in Main, everything works fine again:
function bar()
Main.Foo()
end
expr = Meta.parseall("""
struct Foo end
Main.bar()
""")
Core.eval(Main, expr)
Can someone explain, where the different behavior comes from?
Thank you, that is a good hint. But to be honest, I do not understand, why the binding is necessary, and what makes it even worse, why it’s not enough to bind it to a function local variable, as this is happening in Documenter.jl:
function bar()
Main.Sandbox.Foo()
end
function test()
expr = Meta.parseall("""
struct Foo end
Main.bar()
""")
Sandbox = Module(:Sandbox)
Core.eval(Sandbox, expr)
end
test()
fails again with a "UndefVarError: Sandbox not defined), it is necessary to make the Sandbox binding global.
I don’t know the internals, but it seems to me that separating the creation of a module (which needs a fixed name) and the binding to another module’s namespace (possibly with another name) may be necessary to allow things like this:
julia> import Random as RNDM # I might want `Main.Random` to be a different thing
julia> @isdefined Random
false
julia> RNDM.eval(:@__MODULE__) # But this is the "real" name of the module
Random
With Module(:Sandbox) you are creating the module called Sandbox, but still have the possibility of using Main.Sandbox for a different thing, as in the previous example with the module Random.
I don’t know the answer to that, but I had never seen a module defined as a local object of a function - I didn’t even imagine that it could be allowed.
You comment that this is related to Documenter.jl, whose internals I don’t know, so that may be the reason of my failure to understand what you are trying to do. Could this other topic be related to the problem you report?