I have some complex code that makes more sense as a module. I have done this before with 2 other “local”–as in in my file system–modules and everything works fine. This one just won’t work.
The filename and the module name match. I have noted that this is a requirement that is not documented.
# filename CovidSim.jl
module CovidSim
<code>
end # module CovidSim
This all exists in a directory called “Covid”. I have symlinked this directory into the directory: /users/<myname>/.julia-local-packages
My startup.jl file looks like:
push!(LOAD_PATH, "/Users/<myname>/.julia-local-packages/Covid")
push!(LOAD_PATH, "/Users/<myname>/.julia-local-packages/nn by hand")
push!(LOAD_PATH, "/Users/<myname>/.julia-local-packages/TOML")
try
using OhMyREPL
catch
@warn "OhMyREPL not installed"
end
When I examine the LOAD_PATH environment variable, it is:
When I do using CovidSim there is a bit of a delay and the prompt returns. But, nothing I have exported can be accessed. I cannot access functions qualifying the names such as CovidSim.run_a_sim
It’s as though nothing has happened. Flummoxed.
This housekeeping stuff just gets exhausting and takes lots of time.
Instead of explicitly manipulating LOAD_PATH, it would be easier to directly rely upon Pkg’s features.
In this case, you should probably “develop” your package:
julia> #hit "]" to enter pkg REPL mode
(@v1.4) pkg> dev /Users/<myname>/.julia-local-packages/Covid
From there on, you won’t have to manually fiddle with LOAD_PATH: when you’re in your default environment, using Covid will just work.
That’s awesome. Not portable across machines, but trivial. I assume there is no reason that the project directory containing the module needs to be in any magic directory.
Looks like it requires Julia 1.4 so time to bite that bullet.
By the way, it is actually not required that the file name matches the module name. In fact, you can have multiple modules in one file. In Python, every file is also a module. Julia intentionally avoids this restriction.
…hmmm. Then, how does Julia find the module within a project directory where the directory name is arbitrary? Does Julia open every .jl file and look for a module statement—tricky, because there can be many, as you point out?
The package and module name spaces are a little confusing.
As far as I know, you can only use the package manager to manage packages, not arbitrary source files with modules in them. So there are two approaches you could take:
Manually source the files in your REPL session (or in your startup.jl file) with include("myfile.jl").
Turn your modules into small packages and manage them with the package manager.
It’s pretty easy to wrap your module into a package. Refer to the docs for more info on this.
Package namespaces are actually just modules. Here is the source code for Example.jl:
module Example
export hello, domath
"""
hello(who::String)
Return "Hello, `who`".
"""
hello(who::String) = "Hello, $who"
"""
domath(x::Number)
Return `x + 5`.
"""
domath(x::Number) = x + 5
end
So you can see that the namespace for the Example.jl package is just created with a module.
But, it’s not a package. This does not work. It is a file containing a module, which does a bunch of using’s and includes. generate does not seem to work because it doesn’t ask for enough arguments. It should request a name and a directory for the files.
There is LOTS of conflicting advice and direction around this. One way and one way that works is how this stuff should be. Usually there are not enough benefits to the alternatives to justify having so many ways.
To do that, go into your Packages folder. This can be in Documents or wherever you want. It does not need to be in your .julia folder. Do ] generate MyPackage.
Next close out of julia. Go to your Projects folder and do the same command. You still want to ] generate. So you do ] generate MyProject.
Now you want to let your MyProject know that it can use code from MyPackage. To do this, go into your MyProject folder and do ] activate .. This will create a new environment. I think this might be where you are running into trouble.
Now your package repl should look like
(MyProject) pkg>
What you want do next is
] dev '~/Documents/Packages/MyPackage`
Now using MyPackage should work and you can work on both in tandem.
There is a recommended way: make a project, and activate it, and work in that context. Which is the advice various people have given above. It is not conflicting.
I don’t know where you got the idea to use LOAD_PATH from, but I am guessing you must have seen it in a reply from years ago on some discussion forums. It used to be a workaround, but it is not the recommended way since the new Pkg(3) was introduced.