How to import module from another file in same directory?

2,962 views
Skip to first unread message

Andrei

unread,
Aug 24, 2014, 8:10:58 AM8/24/14
to julia...@googlegroups.com
Let's say I have following project layout:

P.jl that contains module P -- main package module, exposes code from a.jl and b.jl
a.jl that contains module A and
b.jl that contains module B -- some domain specific modules
u.jl that contains module U -- util functions

Now I want to use functions in U from modules A and B. In simplest case I would just include("u.jl") inside of a.jl and b.jl, but this way functions from U will be defined in both - A and B. So I really want to import U, not include u.jl, but I can't do this since u.jl is not on the LOAD_PATH (and messing with it manually looks somewhat bad to me). 

Is there some standard way to tackle it?

(Note, that A, B and U are here just for code splitting, other ways to do same stuff are ok too.)

Valentin Churavy

unread,
Aug 24, 2014, 10:38:53 AM8/24/14
to julia...@googlegroups.com
What you are looking for is described in http://julia.readthedocs.org/en/latest/manual/modules/#relative-and-absolute-module-paths

in P.jl you include all your submodules 
module P
 include
("u.jl")
 include
("a.jl")
 include
("b.jl")

 
using .A, .B

 
export f, g
end

 u.jl 
module U
 g
() = 5
 f
() = 6
end

a.jl and b.jl both lokk like this

module A
 
import ..U

 f
= U.f
 g = U.g

 
export f, g
end

so one dot as a prefix looks in the namespace of the current module and two dots as prefix looks in the namespace of the parent module.

Hope that helps

Andrei Zh

unread,
Aug 25, 2014, 10:29:03 AM8/25/14
to julia...@googlegroups.com
Valentin, thanks for your answer, but it seems like I need to give you some more context (sorry for not mentioning it earlier). I'm trying to repeat my experience of interactive development in languages like Python or Lisp. In these languages I can load some module/file contents to REPL ("__main__" module in Python, "user" namespace in Clojure, etc.) and play around with the code just like if I was "inside" of module under development. E.g. I can modify some function, send new definition to REPL and immediately try it out. I can also import any other modules/packages/namespaces. In Python, for example, being in __main__ (with loaded definitions from target module) I can refer to any other module on PYTHONPATH by its full name. Same thing with Clojure - any namespace on CLASSPATH is available for loading.

In Julia there's Main module too. I can load some code and play around with it, just like in REPLs of other lanuages. E.g. I can start editor, open some file "linreg.jl", send all its contents to REPL, see how it works, update, reload, etc. Works like a charm... until I try to import another module.

Unlike Python or Clojure, Julia's module system is decoupled from source files and directory structure. Correct me if I'm wrong, but it seems like there's no way to load module other than include() its source file. At the same time, I cannot include files all here and there. E.g. in example above when I work on module A (from REPL/Main) I cannot include "P.jl", because "P.jl" contains recursive include() of "a.jl", and they just re-include each other endlessly.

So the only way we can make it work is to load module system from the top level ("P.jl") and then refer to other modules with respect to it (e.g. like "using .A" or "import ..U"). It works fine with third party packages, but I find it really frustrating when working on some internal module (e.g. A).

Thus any tips and tricks on loading modules when working from REPL/Main are welcome.

Tobias Knopp

unread,
Aug 25, 2014, 10:36:18 AM8/25/14
to julia...@googlegroups.com
There is https://github.com/JuliaLang/julia/issues/4600 but there was recently quite some dicussion on the julia-dev mailing list as well as https://github.com/JuliaLang/julia/issues/8014

Cheers,

Tobi

Andrei

unread,
Aug 25, 2014, 5:09:12 PM8/25/14
to julia...@googlegroups.com
Tobias, thanks a lot. From first link I figured out that if module name matches file name, then I can actually import it directly. That is:

# U.jl
module U
f() = 42
end

# A.jl
module A
import U
U.f()
end

Which looks pretty obvious, so that's strange that haven't found it earlier.


Reply all
Reply to author
Forward
0 new messages