To facilitate the reuse of code, WebL allows you to package commonly used routines in a module. An example module might be routines to process pages from a specific web server. Client programs can access the routines by importing the module. This is indicated by the client writing an import statement specifying all the modules that a program requires. After importing a module, the variables declared in that module can be accessed. This is done by writing the module name, followed by an underscore character and the variable name. For example, the following program imports module A, accesses a variable and calls a function in that module:
PrintLn("The value of x in A is ", A_x);
The import statement may occur only at the beginning of a program. Imported variable references must always be explicitly qualified by the module name and an underscore. Note the choice of the underscore character allows us to separate the variable name space and module name space (i.e. a module and a variable might have the same name).
One of the side-effects of importing a module is the loading of the module into memory. WebL keeps track of all loaded modules in a global module list. Before importing a module, the module list is checked to see whether the module has been loaded before -- if so, the previously loaded module is reused. Thus a module can be loaded only once. There is no operation to unload a module.
A module is nothing more than a statement sequence stored in a file with the extension ".webl". Loading a module involves executing this statement sequence (once). The language allows the programmer to export declared variables from the module. The exported variables are visible to clients of the module. Unexported variables cannot be accessed from clients. Exported variables are only allowed in the top level context. For example, in the following implementation of module A (which must be stored in the file "A.webl") the variable y is hidden from clients:
export var Doit = fun() PrintLn("ok.") end
Modules may import other modules. This allows the construction of a module hierarchy in the form of an import graph. Note that the graph is directed and a-cyclic -- recursive module imports are not allowed and will cause a runtime error.