Summary:
See also: Variables, Arrays, Records, Constants, Programs
The GLOBALS instruction can be used to declare variables, constants and types for the whole program.
The concept of global program elements shared by all modules of a program is an old programming concept. To increase code reusability and readability, avoid global elements in your 4GL programs. You better use modular concepts, by defining PUBLIC variables, constants and types in modules that will be imported into other module needing these elements.
GLOBALS
declaration-statement
[,...]
END GLOBALS
GLOBALS "filename"
In general, a program variable, constant or user type is in scope only in the same FUNCTION, MAIN, or REPORT program block in which it was declared.
To extend the scope of a variable, constant or user type beyond the source module in which they are declared, you can declare it as global in a "globals" file:
The filename must contain the .4gl suffix. It can be a a relative or an absolute path. To specify a path, the slash (/) directory separator can be used for Unix and Windows platforms.
Note that if you modify the globals file, you must recompile all the modules that include the file.If a local element has the same name as another variable that you declare in the GLOBALS statement, only the local variable is visible within its scope of reference.
You can declare several GLOBALS blocks in the same module.
A GLOBALS file must not contain any executable statement.
Do not write a declaration statement outside a GLOBALS ... END GLOBALS block in a GLOBALS file.
You do not need to compile the source file containing the GLOBALS block. However, it is recommended to compile the globals file to detect errors.
You can declare several GLOBALS "filename" instructions in the same module.
Although you can include multiple GLOBALS ... END GLOBALS statements in the same application, do not declare the same identifier within more than one GLOBALS declaration. Even if several declarations of a global elements defined in multiple places are identical, declaring any global element more than once can result in compilation errors or unpredictable runtime behavior.
A GLOBALS block can hold GLOBALS "filename" instructions. In such case, the specified files will be included recursively.
Use only a few global variables, too much global variables makes the source code difficult to maintain and denies reusability.
There is no need to compile the globals file, but compiling the file might be useful to detect syntax errors.To improve the readability of your source code, you can prefix global variables by "g_".
Globals files can define the database or the schema to be used by the compiler to resolve DEFINE ... LIKE statements. The schema specification must appear before the GLOBALS keyword starting the globals block:
01
SCHEMA stores02
GLOBALS03
DEFINE cust_rec LIKE customer.*04
...05
END GLOBALS
The schema specification is propagated to the modules including the globals file defining the database schema. These modules can use DEFINE ... LIKE without an explicit SCHEMA instruction.
Further, when using the DATABASE instruction instead of SCHEMA, if the module including the globals contains the MAIN block, the DATABASE specification of the globals file will be propagated and result in an implicit database connection at runtime.
Normally a globals file should only contain a GLOBALS ... END GLOBALS block. However, because the GLOBALS block can also be defined in regular modules, it is possible to include a source containing more than a GLOBALS block. When including such module, the sections before and after the GLOBALS block are ignored by the compiler. The source defining the global elements can be compiled individually.
For example, it is legal to define a module A with a GLOBALS ... END GLOBALS block, followed by function definitions. This module can be compiled and functions will be taken into account. Module A can then be included in module B with a GLOBALS "filename" instruction, and when compiling module B the function definitions of the included module A will be ignored. Note that IMPORT instructions before the a GLOBALS ... END GLOBALS block will also be ignored in such case.
labels.4gl : This module defines the text that should be displayed on the screen
01
GLOBALS02
CONSTANT g_lbl_val = "Index:"03
CONSTANT g_lbl_idx = "Value:"04
END GLOBALS
globals.4gl : Declares a global array and a constant containing its size
01
GLOBALS "labels.4gl" -- this statement could be line 2 of main.4gl02
GLOBALS03
DEFINE g_idx ARRAY[100] OF CHAR(10)04
CONSTANT g_idxsize = 10005
END GLOBALS
database.4gl : This module could be dedicated to database access
01
GLOBALS "globals.4gl"02
FUNCTION get_id()03
DEFINE li INTEGER04
FOR li = 1 TO g_idxsize -- this could be a FOREACH statement05
LET g_idx[li] = g_idxsize - li06
END FOR07
END FUNCTION
main.4gl : Fill in the global array and display the result
01
GLOBALS "globals.4gl"02
MAIN03
DISPLAY "Initializing constant values for this application..."05
DISPLAY "Filling the data from function get_idx in module database.4gl..."06
CALL get_id()07
DISPLAY "Retrieving a few values from g_idx"08
CALL display_data()09
END MAIN10
FUNCTION display_data()11
DEFINE li INTEGER12
LET li = 113
WHILE li <= 10 AND li <= g_idxsize14
DISPLAY g_lbl_idx CLIPPED || li || " " || g_lbl_val CLIPPED || g_idx[li]15
LET li = li + 116
END WHILE17
END FUNCTION