|
|||||
|
|||||
Prerequisite Concepts | Related Syntax | ||||
Modules |
Programmers can manage the complexity of large OmniMark scripts by encapsulating parts of the script into modules. A module is a self-contained unit of OmniMark code that specifies which names are accessible (exported) to its "clients" (importers). Likewise, the importer of a module has control over the names it uses for the things it gets from the module.
By convention, OmniMark modules are placed in files whose names end with the ".xmd
" suffix, in the same way that OmniMark programs use ".xom
" and OmniMark include files use ".xin
".
Modules may be imported by the main program, or by other modules. Modules may use include files.
It is useful to think of a module as being like an "include" file, with several important differences:
Here's a simple module with a function that returns a different (pseudo-random) number each time it's called:
module global integer count initial {1} export integer function next as set count to (count * "ABCDEF97" base 16) shift -1 return count
A module always starts with the keyword module
. module
can be preceded only by comments and white-space.
After that, things are more or less as they are for any other OmniMark code. You can declare globals, constants, functions and opaque types. You can have rules, including process-start
and process-end
rules.
By default, anyone using (importing) a module doesn't see the names within it -- they're hidden. The module can selectively export
names from the module to make them visible to the user (importer) of the module.
(In this example, we're only exporting a single thing from the module. This is just to keep the examples simple. In practice most modules will export many names, and hide many others.)
Once you've defined a module, you can use it in OmniMark programs and other modules by "importing" it:
import "mymodule.xmd" unprefixed
The name after the keyword import
is a file name, just as for an include file. The keyword unprefixed
specifies that all of the names exported by the module will be used "as is".
As an example, if "mymodule.xmd
" is the name of the file containing the pseudo-random number module described above, then the name next
will refer to the next
function exported from the module.
import "mymodule.xmd" unprefixed process repeat to 10 output "10fkd" % next || "%n" again
Sometimes you will want to use two modules that define the same name, or a module that defines a name used by your own code.
You can specify a prefix when importing a module, to keep the names in different modules separate from each other and from your
own names:
import "mymodule.xmd" prefixed by my. process repeat to 10 output "10fkd" % my.next || "%n" again
In this case, all the names imported from "mymodule.xmd" will be referenced as if they had "my.
" prefixed to their names. This means that the my.next
will refer to the function next
defined in the module.
There are no limitations on what you use as a prefix, so long as the result is a valid name. Remember that OmniMark allows "-", "." and "_" in a name, and these are good things to put at the end of prefixes. You should choose prefixes that help make your code clear and readable.
Prerequisite Concepts Functions Rule-based program, basic structure Shelves |
Related Syntax export, export as opaque import, supply, prefixed by, unprefixed, use module require |
Copyright © Stilo International plc, 1988-2008.