How are modules found?

Is there ever a reason to call Base.require directly, or is it a function that
is used only internally by import/using, and I should never call it directly
and forget it exists?

Since the argument to require is a module name, not a filename, which source file is loaded? How does it make the connection between the module name and the file name? The documentation says “When searching for files, require first looks for package code under Pkg.dir(), then tries paths in the global array LOAD_PATH”, but that seems somewhat ambiguous. By extension, since require provides the implementation for import/using, my question is really about how modules are found in those instances, too.

The Julia documentation on Modules says “Files and file names are mostly unrelated to modules; modules are associated only with module expressions”. However, some experimentation seems to indicate that there is a pretty direct link: using MyModule has worked for me in exactly two cases:

  1. There is a file MyModule/src/MyModule.jl in Pkg.dir() that defines a module MyModule

    If the file MyModule/src/MyModule.jl defines a different module than MyModule, that module is actually imported (but not its exported names), but Julia shows a message

    WARNING: requiring "MyModule" in module "Main" did not define a corresponding module.

    If MyModule/src/MyModule.jl defines one or more modules in addition
    to MyModule (e.g. MyModule2 and MyModule3), these modules are imported alongside “MyModule” (again, without their exported names). One can subsequently do using MyModule2to get the exported names inMyModule2, but there seems to be no way to get MyModule2withoutMyModule`. So why would one define more than one module per file? (and arguably: why would this even be allowed?

  2. There is a file MyModule.jl in any directory in LOADS_PATHS. The behavior is pretty much the same as for the package (the file must define the module MyModule and it behaves in the same way regarding other/additional modules defined in the same file.

Are these empirical rules I’m observing the official behavior? Is this spelled
out somewhere in the documentation, in a place I didn’t find?

So in essence it looks to me like Julia uses “Packages” as a way to distribute exactly one module (possibly with submodules, but submodules don’t seem to be encouraged, or at least I haven’t found any of the major packages that use them.

One more question: Is there a way to have multiple directories in Pkg.dir()?

I asked something similar here:

but did not get an answer.

My understanding is that things change with Pkg3 anyway.

Ok… at least you’ve found the same behavior! I looked at the plans for Pkg3, and it seems like this will only add to the places where Packages may be found. Nonetheless, I think any using/import will still require that any module MyModule is in a file MyModule.jl, and (if not directly in LOAD_PATH) in a package MyModule.

This requirement should probably just be added to the documentation. Maybe I’ll do a pull request…