Modules
Modules include programs that contain a set of packages and their sub-packages. It mostly serves to enable a program to use its own packages or to make a package available to other users. In the common scenario it is a set of packages that you import in your code.
Modules standardize your code and outline its main structure. Your module file is a type specifier, the directory where the file is located is considered the parent directory of your module and your compiler processes your code accordingly.
Initialize a Module
To create a module, run the required compiler command in your targeted directory. This will create the necessary files for you and designate your current working directory as your main module package.
For example:
$ julec mod init
Module Files
Module files ensure that the directory in which they are located is determined as the main module directory. A module file is called jule.mod
and acts as a file that provides you with all the required functionality of your module.
Using Modules
It is useful to use modules. It is more difficult to test your projects without using a module because you cannot use Jule's testing functions without a module. Actually maybe you can test it, but using a module is more functional. See writing tests for more information for that.
For most programs it is necessary to write subpackages. It is important for a streamlined and maintainable development experience. You also need to use a module to access sub-packages.
Modules can access sub-packages from the main package through their own package import behavior. This applies to all modules.
For example:
project/
├─ foo/
│ ├─ bar/
│ │ └─ bar.jule
│ │
│ └─ foo.jule
│
├─ jule.mod
└─ main.jule
In the project structure above, the main.jule
file must use foo::bar
to access the bar
package of module. This is because the module directory is the project
directory. Likewise, the foo
package should use foo::bar
instead of bar
.
Nested Modules
Nested modules are supported. In a common scenario, when importing third-party packages, the package also has its own module outside of your own module. In nested modules, the main module for the package is considered its own module. In this way, import paths of packages etc. Sensitive matters are kept safe.
For example:
project/
├─ foo/
│ ├─ bar/
│ │ └─ bar.jule
│ │
│ ├─ foo.jule
│ └─ jule.mod
│
├─ jule.mod
└─ main.jule
In the example above, since main.jule
has a module file, it will import the bar
package with foo::bar
. However, since the foo
package has a module within itself, it is its main package. So it uses bar
to import the bar
package.
In this way, the foo
package was designed as a separate module and became more portable. It should be easy to move to different locations due to its intuitive imports thanks to the module file.