Resolving a module by its name?

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)
   return fqm.eval(expr)

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.

offtopic, but in is a function in julia, maybe another name?

I am not aware of a better way.

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.

1 Like

another way to do that

function eval_module_expr(modules::Array{Symbol, 1}, expr::Expr) 
   return Meta.parse(join(string.(modules),".") * "." * string(expr))

You can use getfield for modules:

julia> using ImageFiltering

julia> m = getfield(Main, :ImageFiltering)

julia> typeof(m)

julia> m2 = getfield(m, :KernelFactors)

julia> typeof(m2)

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)

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.


Thank you! This is exactly the right solution, and what I needed.

Could I ask for my own edification: what is the purpose of evaluating an expression in a module? What is your use case, for instance?

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.)

Thanks. Looking forward to trying this. I miss SLIME.

1 Like