You should not have to use include
.
julia> begin
mkpath("modules")
write("modules/test.jl",
"module test end")
push!(LOAD_PATH, "./modules")
using test
end
[ Info: Precompiling test [top-level]
Make sure the file containing the module also has the same name. Also, I would use the absolute path in case you change the working directory.
push!(LOAD_PATH, abspath("./modules"))
Note that Julia conventions are to capitalize module names and use CamelCase for multiple words. There is also a standard library called “Test”.
Manipulating LOAD_PATH
like this is going to get messy in the long run.
For multiple packages, I suggest using Pkg.develop
.
https://pkgdocs.julialang.org/v1/managing-packages/#developing
Then the paths to different packages can be tracked via your project’s Manifest.toml.
Also see the Code Loading section of the manual.
https://docs.julialang.org/en/v1/manual/code-loading/
The canonical way to organize the code is as follows.
julia> begin
using Pkg
Pkg.generate("modules/X")
Pkg.activate(".")
Pkg.develop(path=abspath("modules/X"))
using X
end
Generating project X:
modules/X/Project.toml
modules/X/src/X.jl
Activating project at `~`
Resolving package versions...
Updating `~/Project.toml`
[671976cc] + X v0.1.0 `~/modules/X`
Updating `~/Manifest.toml`
[671976cc] + X v0.1.0 `~/modules/X`
Precompiling X
1 dependency successfully precompiled in 1 seconds
julia> run(`tree modules/X`);
modules/X
├── Project.toml
└── src
└── X.jl
1 directory, 2 files
julia> run(`cat "modules/X/Project.toml"`);
name = "X"
uuid = "671976cc-d390-4257-a514-cd9c3c96f4a5"
authors = ["root "]
version = "0.1.0"
julia> run(`cat "modules/X/src/X.jl"`);
module X
greet() = print("Hello World!")
end # module X
This seems to be a followup to your previous question about code organization. As you noticed there, often your types (usually structs) have to be declared first. Some examples may be useful.
For small to moderate size packages, I would just use a flat structure without deeply nested modules. An example of this is the types.jl file in HDF5.jl:
On the other extreme is when the types are in a distinct package. These “Core” packages mostly contain just the types:
Meanwhile most of the methods may be defined in the main package: