Lesson 6: Modules

edit

In this lesson, you will gain an understanding of D's module system. A module is a unit of code that contains definitions for variables, functions, and other D constructs that belong together. This is useful for creating reusable code. You've seen modules in every single lesson. In fact, all D source files are modules. The stdio module contains functions like writeln. The module stdio is written in a file called stdio.d at dmd/src/phobos/std/stdio.d. It contains code that is useful for console input and output and file input and output. It is within a package called std, which also contains modules such as std.algorithm or std.string, which you will learn about later. The Phobos library is just a big collection of modules that comes with a D compiler.

Introductory Code

edit
// main.d
module main;

import std.stdio;
import module1;
import byebye : sayBye;
 
void main()
{
    happy();
    writeln("Mothers Day!");
    sayBye();
    // sayByeInItalian(); undefined identifier 'sayByeInItalian'
}
// happy.d
module module1;

import std.stdio;

void happy()
{
    write("Happy ");
}

private void sad()
{
    write("Who gives a darn about ");
}

private:
void mad() { }
void bad() { }
//bye.d
module byebye;
import std.stdio;

void sayBye()
{
    writeln("Goodbye!");
}

void sayByeInItalian()
{
   writeln("Arrivederci");
}

Compile like this: dmd main.d happy.d bye.d

Concepts

edit

A Deeper Look at Imports

edit

All D code is inside modules. In D programs, there has to be one module with a main function. If one module imports another module, the imported module's definitions becomes available to the first module. In the introductory code, the main module imported two other modules: module1 and byebye. However, when byebye was imported, only one function was imported: the sayBye function. The syntax for that is import modulename : identifier1, identifier2, identifier3;.

Module Declarations

edit

D source files can specify the name of the module and what package it belongs to with a module declaration, which goes at the beginning. For example, in the stdio module, there is this line:

module std.stdio;

That line specifies the name of the module (stdio) and the package it is located in (std). Each source file can only have a maximum of one module declaration. If there is none, the source file name (without the extension) becomes the module name.

Visibility

edit

Before the void in the definition of sad in module1, you see the modifier private. That means that the sad function cannot be imported. You wouldn't be able to do import module1 : sad, either. If you see a line that says private:, everything below that line is private. Likewise, if you see private { } , everything inside the curly brackets is private.

Tips

edit
  • The name of the module does not have to relate to the names of the definitions within that module.
  • The name of the module does not have to relate to the file name.
  • There is also a public modifier, which is the opposite of the private modifier. Declarations marked by neither public nor private are public by default.
  • All D source files are modules, even if there is no module declaration in the file.