Back to Contents


Globals

Summary:

See also: Variables, Arrays, Records, Constants, Programs


Definition

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.


Syntax

Syntax 1: Global block declaration

GLOBALS
  declaration-statement
 
[,...]
END GLOBALS

Syntax 2: Importing definitions from a globals file

GLOBALS "filename"

Notes:

  1. In Syntax 1, declaration-statement is a variable, constant or user type declaration.
  2. In Syntax 2filename is the name of a file containing the definition of globals. Use this syntax to include global declarations in the current module.

Usage

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:

  1. Declare global elements in a GLOBALS … END GLOBALS block in specific files.
  2. Import the global symbols in other modules with GLOBALS "filename" statements.

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_".


Database schema declaration in globals

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 stores
02 GLOBALS
03   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.


Content of a globals file

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.


Examples

Example 1: Multiple GLOBALS file

labels.4gl : This module defines the text that should be displayed on the screen

01 GLOBALS
02   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.4gl                                                                                                                                    
02 GLOBALS
03   DEFINE g_idx ARRAY[100] OF CHAR(10)
04   CONSTANT g_idxsize = 100
05 END GLOBALS

database.4gl : This module could be dedicated to database access

01 GLOBALS "globals.4gl"
02 FUNCTION get_id()
03   DEFINE li INTEGER
04   FOR li = 1 TO g_idxsize -- this could be a FOREACH statement
05       LET g_idx[li] = g_idxsize - li
06   END FOR
07 END FUNCTION

main.4gl : Fill in the global array and display the result

01 GLOBALS "globals.4gl"
02 MAIN
03   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 MAIN                                                                                                                                    
10 FUNCTION display_data()
11   DEFINE li INTEGER
12   LET li = 1
13   WHILE li <= 10 AND li <= g_idxsize
14       DISPLAY g_lbl_idx CLIPPED || li || " " || g_lbl_val CLIPPED || g_idx[li]
15       LET li = li + 1
16   END WHILE
17 END FUNCTION