Organizing modules in packages
Modules to be imported can be grouped in packages.
Package basics
Structuring your sources is important for maintenance, readability, reusability and deployment.
top-dir/
|-- mylibs/ -- package: mylibs
| |-- myutils/ -- package: mylibs.myutils
| | |-- fileutils.4gl
| | |-- sqlutils.4gl
| ...
|-- webserv/ -- package: webserv
| |-- stock.4gl
| |-- shipment.4gl
| ...
...
|-- starter.4gl -- main programs
|-- reports.4gl
A sequence of directories defines a package-path. In a
package-path, package names are separated by a dot. In the above structure, the
package-path "mylibs.myutils
" corresponds to the directory path
"mylibs/myutils", relative to "top-dir".
Use simple regular identifiers for package and module names, using ASCII characters. Do not use names such as "1mod", "forêt", "module-1.4gl".
Declaring a module for a package
In order to indicate that a module belongs to a package, use the PACKAGE
instruction at the top of the
module source.
mylibs.myutils
package:PACKAGE mylibs.myutils
PUBLIC FUNCTION getSubDirs(path STRING) RETURNS ...
...
END FUNCTION
Importing package modules
IMPORT FGL
instruction, followed by a dot and the module
name:IMPORT FGL mylibs.myutils.fileutils
PUBLIC FUNCTION file_browser(defpath STRING) RETURNS (INTEGER,STRING)
DEFINE dirs DYNAMIC ARRAY OF STRING
CALL mylibs.myutils.fileutils.getSubDirs(defpath) RETURNING dirs
...
END FUNCTION
IMPORT FGL
is a
package-path, that must reflect the directory path based on the
top-dir of the sources, using dots as separators. For example, to import the
"fileutils
" module from the
top-dir/mylibs/myutils directory,
use:IMPORT FGL mylibs.myutils.fileutils
.*
syntax:IMPORT FGL mylibs.myutils.*
When a module under a package wants to import a sibling module, specify the full package-path in IMPORT FGL:
mylibs.myutils
package, in
top-dir/mylibs/myutils:PACKAGE mylibs.myutils
PUBLIC FUNCTION getSubDirs(path STRING) RETURNS ...
...
END FUNCTION
mylibs.myutils
package/directory:PACKAGE mylibs.myutils
IMPORT FGL mylibs.myutils.fileutils
PUBLIC FUNCTION findConfigFile(path STRING) RETURNS STRING
...
CALL mylibs.myutils.fileutils.getSubDirs("/opt/myapp") RETURNING ...
...
END FUNCTION
Module aliases
AS
keyword:IMPORT FGL mylibs.myutils.fileutils AS fu
...
CALL fu.getSubDirs(defpath) RETURNING dirs
Note that the alias provided with IMPORT FGL … AS …
is a module alias. There is
no way to define a package-path alias.
Finding modules with FGLLDPATH
For compilation and at runtime, a root-path
defined in the
FGLLDPATH environment variable will be used to
find a package module as
root-path/package-path/module-name[.4gl|.42m]
.
FGLLDPATH typically contains the top-dir of the package path.
For example, with the following package/directory structure:
top-dir/
|-- mylibs/
| |-- myutils/
| | |-- fileutils.4gl
| | |-- sqlutils.4gl
|-- app1/
| |-- main.4gl
$ cd top-dir
$ export FGLLDPATH=$PWD
$ cd app1
$ fglcomp -M --verbose main.4gl
[parsing top-dir/mylibs/myutils/fileutils.4gl]
[building mylibs/myutils/fileutils]
[writing top-dir/mylibs/myutils/fileutils.42m]
[parsing top-dir/mylibs/myutils/sqlutils.4gl]
[building mylibs/myutils/sqlutils]
[writing top-dir/mylibs/myutils/sqlutils.42m]
[parsing main.4gl]
[building main]
[writing main.42m]