I’m very confused on how to create a new module in Julia v0.7. Even the following doesn’t work:
julia> module Foo
end
Main.Foo
julia> using Foo
ERROR: ArgumentError: Module Foo not found in current path.
Run `Pkg.add("Foo")` to install the Foo package.
Stacktrace:
[1] require(::Module, ::Symbol) at ./loading.jl:868
Another issue: I have a new package Foo
I’ve created with file .julia/dev/Foo/src/Foo.jl
consisting of:
module Foo
using Base
# using LinearAlgebra
end
This works fine. But if I uncomment using LinearAlgebra
I get the error:
julia> using Foo
ERROR: LoadError: ArgumentError: Module LinearAlgebra not found in current path.
Run `Pkg.add("LinearAlgebra")` to install the LinearAlgebra package.
Stacktrace:
[1] require(::Module, ::Symbol) at ./loading.jl:868
[2] include at ./boot.jl:314 [inlined]
[3] include_relative(::Module, ::String) at ./loading.jl:1071
[4] _require(::Base.PkgId) at ./loading.jl:997
[5] require(::Base.PkgId) at ./loading.jl:878
[6] require(::Module, ::Symbol) at ./loading.jl:873
in expression starting at /Users/sheehanolver/.julia/dev/Foo/src/Foo.jl:3
Even though other packages I have installed also call using LinearAlgebra
.
An update: I sort of figured out how to solve the second problem:
- Delete all references to Foo.jl in .julia
- In a new location, run
generate Foo
in Pkg mode
- cd into the new Foo directory
- Call
add LinearAlgebra
in Pkg mode
- Copy-and-paste the existing src code that called
using LinearAlgebra
inside of Foo
- ^D out of julia so it forgets I ever ran
using Foo
(how dare I!!)
- Open a new julia session
- cd again into the new Foo directory
- Now call
using Foo
and it works!
- There is no step 10
I haven’t figured out how to get using Foo
to work without first cding into its directory… make a link in .julia/dev
didn’t work.
It actually not related to the version. When you create a module in current scope, you need to load it as a local module:
module Foo
end
using .Foo
or just use its full path
using Main.Foo
It actually not related to the version
Not sure what you mean, this is definitely new to Julia v0.7:
julia> versioninfo()
Julia Version 0.6.2
Commit d386e40c17 (2017-12-13 18:08 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin17.3.0)
CPU: Intel(R) Core(TM) i5-7600K CPU @ 3.80GHz
WORD_SIZE: 64
BLAS: libgfortblas
LAPACK: liblapack
LIBM: libopenlibm
LLVM: libLLVM-3.9.1 (ORCJIT, broadwell)
julia> module Foo end
Foo
julia> using Foo
julia>
Oh, sorry, didn’t notice this, I was wrong. I think this is about make things consistent.
in julia, everything is evaluated in module Main
, and if the module is defined inside it, it should either
provide a relative path or an absolute path. In v0.6 if you define a module by yourself
module Foo
module Foo2
end
using Foo2
end
this will be wrong. You should use
module Foo
module Foo2
end
using .Foo2
end
and in REPL, what you write is actually inside module Main
, therefore, it should use relative path or absolute path.
1 Like
OK, I think I figured it out:
(v0.7) pkg> add /path/to/Foo.jl
(v0.7) pkg> develop /path/to/Foo.jl
Then I can call using Foo
without being in the right directory.
Should be no need to add
first.
Why do you think it would be better to do pkg> develop /path/to/Foo.jl
rather than pkg> add /path/to/Foo.jl
? (I am just trying to understand the philosophy of the package manager.) Thanks.
The way add local_repo_path#branch
works is exactly the same as add external_repo_url#branch
. Track the git repository at the path / url and use update
to get new commits on the branch you track.
Note that only using add
means that your project has an immutable state and will work the same whenever you get back to it.
dev
is used when you want to point to a path and use the (mutable) state of the files there. There is no longer any guarantee that the project will work the same next time you get back to it, the files are no longer considered immutable and might have been changed since last time you used the project.
1 Like
How does it choose which version to use? I.e. the one in dev/ vs one in packages/?
If the manifest has a path
entry it uses that path. If the manifest does not have a path
entry the path is computed based on git-tree-sha
and is loaded from packages
. dev
puts a path entry into the Manifest.
OK, I think I understand. .julia/environments/v0.7
is the default “project”, but is otherwise treated the same as all other projects. If I was stubborn and wanted to manage the packages available by hand, I would need to edit Manifest.toml by adding
[[Foo]]
deps = ["LinearAlgebra"]
path = "/path/to/Foo.jl"
uuid = "?????"
version = "0.0.0"
Where I would somehow need to figure out the UUID of Foo.jl. What typing
(v0.7) pkg> develop /path/to/Foo.jl
does is adds these lines, with the correct UUID, to Manifest.toml
Ojn the other hand,
(v0.7) pkg> add BenchmarkTools
just adds
[[BenchmarkTools]]
deps = ["Compat", "JSON"]
git-tree-sha1 = "ea054fbc1f71dd1544b0c4dc5623e059aba288c0"
uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
version = "0.3.1"
that is, it doesn’t specify a path, so instead of loading from the specified path, it loads from .julia/packages/
, using the UUID and version to choose the right package. If then type
(v0.7) pkg> develop BenchmarkTools
it clones BenchmarkTools.jl to .julia/dev/BenchmarkTools
, and modifies Manifest.toml by adding path = ~/.julia/dev/BenchmarkTools
, so using BenchmarkTools
looks for the package at the specified path.
3 Likes