How to add/create/use submodules?

In the documentation for modules, I understand that the name of a module (or submodule) does not necessarily have to be the same as the module name - since the module name is a namespace. I’m having trouble loading a submodule - but I’m also sure I’m missing something important.

Once I figure everything out, I will start with PkgTemplates, buf for simplicity here I created an example project with ] generate Stuff, I then created a file in Stuff/src: crc.jl.

The file contains code like:
module CRC
export crc

table::Vector{UInt32} = Vector{UInt32}(undef, 256)

function compute_table()
    # code elided
end

function __init__()
    compute_table()
end

function crc(buffer)
    # code elided
end

end # module CRC

I’m aware that there are several very mature projects that compute CRCs, this is just something that was handy to use as an example. I was hoping, in Stuff/src/Stuff.jl, to be able to use the crc function that was exported from the submodule by issuing using .CRC … but the local module is not found.

Did I need to add my code to the project with ] dev or something?

EDIT: Thanks to @disberd for pointing out that one has to use using .CRC in this case.

# src/Stuff.jl
module Stuff

include("crc.jl")
using .CRC

end
ERROR: LoadError: ArgumentError: Package Stuff does not have CRC in its dependencies:
] add .CRC
ERROR: Unable to parse `.CRC` as a package.

I picked the submodule name CRC on purpose - because it collided with a package that was in the global repository, so that I could better understand how modules worked …

I think here you’d have to write

using .CRC

as without the . it will look for a package named CRC inside the package environment.
WIth the . you are specifying to reference to the locally defined submodule CRC.

For submodules that are not packages themselves (but are simply defined in the parent module namespace like with include("crc.jl") above) you don’t have to use ]add

1 Like

Here is a simplified example. The example package has a file structure like:

.
├── Project.toml
└── src
   ├── crc.jl
   └── Stuff.jl

In crc.jl:

module CRC
export crc

crc(buffer) = 0x01020304

end # module CRC

And in Stuff.jl:

module Stuff

include("crc.jl")
using .CRC # note the leading dot!

end # module Stuff

Now, since the CRC module exported crc from CRC to Stuff, we can do:

julia> using Stuff

julia> Stuff.crc
crc (generic function with 1 method)

To also have crc exported from Stuff, you’d need another export statement in Stuff.jl

3 Likes

Indeed, you are right, my bad. I update my answer!