Module
Explore the fundamentals of modules in D programming, including module naming, the use of static constructors and destructors, and how packages group related modules. This lesson helps you understand how to structure your D projects using modules and libraries for better program organization and efficiency.
We'll cover the following...
Module overview
The building blocks of D programs (and libraries) are modules.
D modules are based on a simple concept: Every source file is a module.
Accordingly, the single files that we have been writing for our programs have all been individual modules.
By default, the name of a module is the same as its filename without the .d extension. When explicitly specified, the name of the module is defined by the module keyword, which must appear as the first non-comment line in the source file.
For example, assuming that the name of a source file is “cat.d,” the name of the module would be specified by the module keyword:
module cat;
class Cat {
// ...
}
The module line is optional if the module is not part of any package (see below). When unspecified, it is the same as the file name without the .d extension.
static this() and static ~this()
static this() and static ~this() at module scope are similar to their struct and class counterparts:
module cat;
static this() {
// ... the initial operations of the module ...
}
static ~this() {
// ... the final operations of the module ...
}
The code that is in these scopes is executed once for each thread.
Note that most programs consist of a single thread that starts executing the
main()function.
Code that should be executed only once for the entire program (e.g., initializing shared and immutable variables) must be defined in shared static this() and shared static ~this() blocks, which will be covered in the data sharing concurrency chapter.
File and module names
D supports Unicode in source code and module names. However, the Unicode support of file systems vary. For example, although most Linux file systems support Unicode, the file names in the Windows file systems may not distinguish between lower and upper case letters. Additionally, most file systems limit the characters that can be used in file and directory names.
For portability reasons, we recommend that you use only lowercase ASCII letters in file names. For example, “resume.d” would be a suitable file name for a class named Résumé.
Accordingly, the name of the module would consist of ASCII letters as well:
module resume; // Module name consisting of ASCII letters
class Résumé { // Program code consisting of Unicode characters
// ...
}
Packages
A combination of related modules is called a package. D packages are a simple concept as well; the source files that are inside the same directory are considered to belong to the same package. The name of the directory becomes the name of the package, which must also be specified as the first parts of module names.
For example, if “cat.d” and “dog.d” are inside the directory “animal,” then specifying the directory name along with the module name makes them a part of the same package:
module animal.cat;
class Cat {
// ...
}
Similarly, for the dog module:
module animal.dog;
class Dog {
// ...
}
Note: For modules that are parts of packages, the module line is not optional and the whole module name including the package name must be specified.
Since package names correspond to directory names, the package names of modules that are deeper than one directory level must reflect that hierarchy. For example, if the “animal” directory included a “vertebrate” directory, the name of a module inside that directory would include vertebrate as well:
module animal.vertebrate.cat;
The directory hierarchies can be arbitrarily complex depending on the needs of the program. Relatively short programs usually have all of their source files in a single directory.