D Programming - Modules


Advertisements


Modules are the building blocks of D. They are based on a simple concept. Every source file is a module. Accordingly, the single files in which we write the programs are 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, assume that the name of a source file is "employee.d". Then the name of the module is specified by the module keyword followed by employee. It is as shown below.

module employee;

class Employee {
   // Class definition goes here. 
}

The module line is optional. When not specified, it is the same as the file name without the .d extension.

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 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, I recommend that you use only lower case ASCII letters in file names. For example, "employee.d" would be a suitable file name for a class named employee.

Accordingly, the name of the module would consist of ASCII letters as well −

module employee;  // Module name consisting of ASCII letters 

class eëmployëë { }

D Packages

A combination of related modules are 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 "employee.d" and "office.d" are inside the directory "company", then specifying the directory name along with the module name makes them be a part of the same package −

module company.employee; 
 
class Employee { }

Similarly, for the office module −

module company.office; 
 
class Office { }

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 "company" directory included a "branch" directory, the name of a module inside that directory would include branch as well.

module company.branch.employee;

Using Modules in Programs

The import keyword, which we have been using in almost every program so far, is for introducing a module to the current module −

import std.stdio;

The module name may contain the package name as well. For example, the std. part above indicates that stdio is a module that is a part of the std package.

Locations of Modules

The compiler finds the module files by converting the package and module names directly to directory and file names.

For example, the two modules employee and office would be located as "company/employee.d" and "animal/office.d", respectively (or "company\employee.d" and "company\office.d", depending on the file system) for company.employee and company.office.

Long and Short Module Names

The names that are used in the program may be spelled out with the module and package names as shown below.

import company.employee; 
auto employee0 = Employee(); 
auto employee1 = company.employee.Employee();

The long names are normally not needed but sometimes there are name conflicts. For example, when referring to a name that appears in more than one module, the compiler cannot decide which one is meant. The following program is spelling out the long names to distinguish between two separate employee structs that are defined in two separate modules: company and college..

The first employee module in folder company is as follows.

module company.employee; 
 
import std.stdio;
  
class Employee {
   public: 
      string str; 

   void print() {
      writeln("Company Employee: ",str); 
   } 
}	

The second employee module in folder college is as follows.

module college.employee;
  
import std.stdio;  

class Employee {
   public: 
      string str;
	
   void print() {
      writeln("College Employee: ",str); 
   } 
}

The main module in hello.d should be saved in the folder which contains the college and company folders. It is as follows.

import company.employee; 
import college.employee; 
 
import std.stdio;  

void main() {
   auto myemployee1 = new company.employee.Employee();
   myemployee1.str = "emp1"; 
   myemployee1.print();
   
   auto myemployee2 = new college.employee.Employee(); 
   myemployee2.str = "emp2"; 
   myemployee2.print(); 
}

The import keyword is not sufficient to make modules become parts of the program. It simply makes available the features of a module inside the current module. That much is needed only to compile the code.

For the program above to be built, "company/employee.d" and "college/employee.d" must also be specified on the compilation line.

When the above code is compiled and executed, it produces the following result −

$ dmd hello.d company/employee.d college/employee.d -ofhello.amx 
$ ./hello.amx 
Company Employee: emp1 
College Employee: emp2


Advertisements