5.3 Import with use

Availability

Since IDM version A.06.02.g

5.3.1 The Alternative Import Mechanism

In addition to the way of accessing a module through an import object, the keyword use can be utilized to facilitate the handling of imports, modules, interface and binary files.

In contrast to an import, the module is not selected by means of a file path to the interface file, but rather by an identifier path – more precisely the Use Path.

The last identifier in a Use Path is, similar to the identifier of an import, the parent identifier that is used to make the exported objects known in the importing module. The preceding identifiers in the Use Path define a package hierarchy and can therefore be used to organize the modules. These parts will be ignored when object paths are evaluated.

Example

!! file: Main.dlg

dialog MainDlg

use Models;
use Base.Fonts;

MWiMain WiMain {
  .font Fonts.FnBig;
}
!! file: Models.mod

module ModModels

export window MWiMain {
  on close {
    exit();
  }
}
!! file: Base/Fonts.mod

module ModFonts

export font FnBig "24.Arial";

The directories in which the actual module and interface file is searched can be set as a command line option or a specific environment variable, with a call of DM_ControlEx() or in the Rule Language.

The existence of an interface file is actually not mandatory, but useful to facilitate loading of modules without direct usage and to support loading of the implementation as needed.

5.3.1.1 Special Features

Modules that are accessed via use are only loaded once in the dialog. This facilitates the use of base modules, since a module is not accidentally loaded several times due to a faulty import chain.

The decoupling from an interface or module file name has several advantages:

  1. Using dedicated environment variables for the locations of interface and binary modules is no longer necessary.
  2. The generation of interface and binary files is simplified.
  3. It is now possible to load modules without an interface file, since a universal search path for interfaces, modules and binary modules is available.

Another special feature is the presetting of file extensions (file suffixes) for source code files (.dlg and .mod), interface files (.if) and binary files (.bin).

The conversion from a Use Path to a file path is done like this: The preceding package identifiers correspond to a directory path, the last identifier to the base name of the module.

In the example above, this means that for the Use Path Base.Fonts, the base file name Base\Fonts results. The source module has the name Base\Fonts.mod, the associated interface file is Base\Fonts.if and the binary module is Base\Fonts.bin.

If a module is now accessed by use Base.Fonts, it will be searched for these three file names in the search path to load the interface or implementation. In the development version of the IDM, the sequence is interface file → source code file → binary module. The runtime version of the IDM can only load binary files.

Some more differences to the import object exist: There are no control options through the attributes .application, .static and .load. It is always attempted to use the interface first and then the implementation (source code, binary). The implementation is only loaded when needed. Direct control of the loading is therefore not available.

For dynamic loading and unloading the new methods :use() and :unuse() are provided.

Basically, binary modules and interface files generated for usage with an import object also work unchanged with use. Conversely, this is not necessarily the case since here the reference to the module path is usually missing in the interface.

5.3.1.2 Upper and Lower Case in File Names

It is important for identifiers in the IDM and therefore also for the Use Path as well as for the file names!

5.3.1.3 Recommendations

Although a mixture of import and use is possible, it is not recommended, since the import object provokes multiple loading of modules. It is therefore recommended to switch completely from import to use.

It is also recommended to use the same spelling for file and directory names as in the Use Path. At best modules should have a unique name which does not appear in some varied form with differing upper and lower case.

Instead of loading a module with import, one should use Models that can be instantiated more than once without problems.

5.3.2 Language Specification and Use Path

The following language specification applies to the use keyword:

{ export | reexport } use { <Use Path> }

<Use Path>     ::= [ <package path> ] <Identifier>
<package path> ::= [ <package path> ] <Identifier> .

An identifier should begin with an uppercase letter ('A' – 'Z') and may then also contain lowercase letters, digits and underscores ('_'). An identifier may have up to 31 characters at most.

Examples for Valid Usages of use

use Defaults;
use DEFAULTS;
use Max_Wi09_;
use Modul78.Aa.MasterA__1z;
use BaseMod.M_ods.Wins.MWiEnter1_9;

The Use Path consists of an identifier at the end and represents the base name of the module as well as the parent identifier for further access to the exported objects (if these cannot be resolved uniquely). This identifier does not necessarily have to be the same as the module identifier.

The package path, in turn, is used to logically structure several modules and is prepended as a directory chain when searching for the module.

5.3.3 Use Path, File Names and Name Restrictions

The IDM internally converts a Use Path into a file path to be used for searching the interface file, source code file or binary module.

Thus the Use Path Modul78.Aa.MasterA__1z becomes the file path Modul78\Aa\MasterA__1z.

In addition, there is a predefined set of file extensions that are relevant for search and access and are internally appended to the base file path:

File Extension

Meaning

.dlg

source code of a dialog

.mod

source code of a module

.if

interface file

.bin

binary file of a dialog or module

Since the Use Path is built from IDM identifiers, this of course means file and directory names may begin with uppercase letters as well as upper and lower case has a meaning and is important! This has to be observed in case of working on file systems that do not distinguish these.

In the IDM this means: use Default; is something else than use DEFAULT;. On Windows, however, the module may be found if a module file DEFault.Mod exists.

In principle, the dialog can also be accessed (loaded) via a Use Path.

If there are unresolvable problems with the conversion between Use Path and file path, the internal conversion behavior can be controlled with the ‑IDMusepathmodifier option.

5.3.4 Search Path for Interface, Module, Dialog, and Binary Files

The IDM possesses a universal search path for finding IDM files. This search path may contain one or more absolute or relative directory specifications separated by semicolons (;).

By default, the search path is set to ~;, thus to the special path ~ and the empty path "". These have the following meaning:

~ or ~:

Search beneath the directory in which the application is located.

"" (empty path)

Search in the current working directory (same behavior as in previous versions).

<ENVNAME>:

Search in the paths that are defined in the environment variable <ENVNAME>.

When searching for an IDM file, e.g. via DM_LoadDialog() or the built-in function load(), proceeding is like this:

  1. If the given path is absolute, the file will be searched for at the exactly given path without appending an extension (compatible behavior as before).
  2. In case of a relative path with file extension, this will be searched for in the search path with exactly that extension. The default entry ""(empty path) shows the compatible behavior as before.
  3. If the file name does not have an extension, the possible extensions are tried for all search paths, depending on the action. For example, DM_LoadDialog() tries the extensions .dlg, .mod, .bin. For a use it is attempted with priority to get the interface, so the sequence .if, .bin, .mod is tried.

These are the available possibilities for setting the search path:

For a self-built IDM application it is recommended to use DM_ControlEx() in the AppMain() routine with an application-relative path using ~ and without other relative specifications like the empty path or ".". So the invocation of DM_ControlEx((DM_ID)0, DMF_SetSearchPath, "~:dlg") would ensure that the dialog files are only searched in the subdirectory dlg parallel to the application. Once the search path is set, initial loading of the main dialog may also take place via DM_LoadDialog() using a relative file path without file extension.

Examples of Correct and Permitted Search Paths

""
"."

Searches in the current working directory.

"~"

Searches in the directory where the application is located.

"if;bin;mods;customer/modules"

 

"~:dlg;~:../mods;."

 

".;MODPATH:if;MODPATH:bin"

Searches in the working directory as well as in the bin and if directories within the directories defined in the environment variable MODPATH.

When opening and loading IDM files, the IDM attempts to determine the file type to recognize whether the file is an interface file, dialog, module, or binary file. For this purpose, the first 1,024 bytes of the file are examined , whether they contain the signature of an IDM binary file or the appropriate keywords identifying an interface, dialog, or module. Otherwise, the file extension is used for determination.