Given an arbitrary module name as a symbol, and an expression, what is the correct way to evaluate the expression in the context of the module?
For example, suppose I have the following tuple:
in = (ns = :MyModule, expr = :(x = 3 + 3))
Assume MyModule has been previously defined. Now I want to evaluate expr inside that module. The best I came up with is:
(@eval $(in.ns)).eval(in.expr)
Using @eval to convert a symbol to a module feels dirty, but I can’t find a getmodule function which could take a symbol and return a module. Am I missing anything?
Edit 1: Follow-up question. What is the right approach to dealing with nested submodules? Let’s say the ns field in the tuple is set to [:MyModule, :One, :Two, :Three], and the module in which I want to evaluate the expression is MyModule.One.Two.Three.
Edit 2: I came up with the following function which seems to do what I want:
function eval_module_expr(fully_qualified_module_name::Array{Symbol, 1}, expr::Expr)
fqm = Main.eval(first(fully_qualified_module_name))
for m in fully_qualified_module_name[2:end]
fqm = fqm.eval(m)
end
return fqm.eval(expr)
end
Use as follows: eval_module_expr([:MyModule, :One, :Two, :Three], :(x = 3 + 5)). Is this a reasonable approach? It feels like I’m reinventing the wheel.
Can you give some context to your problem? It seems like you are doing something quite convoluted, (possibly for macros?). This is occasionally necessary but there may be a simpler solution.
One subtlety is that not all modules are known to Main, specifically, packages loaded to support other packages that you didn’t explictly import into Main. Base.loaded_modules has a list. You can also do this:
julia> using ImageFiltering
julia> ColorTypes
ERROR: UndefVarError: ColorTypes not defined
julia> m = Base.root_module(Base.__toplevel__, :ColorTypes)
ColorTypes
Finally, to evaluate your expression in a particular module you can use Core.eval(mod, expr).
In general, base/reflection.jl, base/loading.jl, and the Serialization stdlib are fantastic resources for these kinds of questions.
I’m hacking on a Julia interaction mode for Emacs in the spirit of Common Lisp’s SLIME and Clojure’s CIDER — both of which are superb, (pretty much) best-of-breed interactive programming environments, and which I miss when I use all other languages. Some features — like putting the current top-level form into the running REPL or system image — require evaluating Julia code in the context of the module where it is defined. These modules can be arbitrarily nested. Hence the need to resolve the module and eval things.
The Cider environment looks super powerful. (Except that my wrists hurt just hearing about all those control-meta-something-or-other key combinations.)