The types of blocks that can occur in a WFL job are the outer block and any SUBROUTINE declarations in the job. The scope of a declaration in WFL is limited to the following blocks:
-
The block in which the declaration occurs
-
Any blocks that are nested in the declaration block and that occur after the declaration
The following WFL example illustrates the effects of these scope rules:
100 ?BEGIN JOB; 110 INTEGER OUTERINT1; 120 SUBROUTINE FIRSTSUB; 130 BEGIN 140 INTEGER FIRSTINT; 150 SUBROUTINE NESTEDSUB; 160 BEGIN 170 INTEGER NESTEDINT; 180 OUTERINT1:= 3; 190 FIRSTINT:= 3; 200 NESTEDINT:= 3; 210 END NESTEDSUB; 220 OUTERINT1:= 2; 230 FIRSTINT:= 2; 240 END FIRSTSUB; 250 INTEGER OUTERINT2; 260 OUTERINT1:= 1; 270 OUTERINT2:= 1; 280 ?END JOB
This example includes three procedures: the outer block of the job and two subroutines, of which NESTEDSUB is nested within FIRSTSUB. Each procedure includes integer variable declarations. Additionally, each procedure that is within the scope of an integer variable declaration includes a statement making an assignment to the integer variable.
Thus, the integer variable OUTERINT1 can be used by statements in the outer block, the FIRSTSUB subroutine, and the NESTEDSUB subroutine. This is because the scope of a declaration includes the procedure it is declared in and all nested procedures. By contrast, the integer variable OUTERINT2 cannot be used by statements in FIRSTSUB or NESTEDSUB, because these subroutines are declared prior to OUTERINT2.
The integer variable FIRSTINT can be used by statements in FIRSTSUB, because FIRSTINT is declared in FIRSTSUB; and by statements in NESTEDSUB, because it is nested in FIRSTSUB. However, FIRSTINT cannot be used by statements in the outer block, because the outer block is not nested inside FIRSTINT.
The integer variable NESTEDINT can be used only by statements in NESTEDSUB, because no other procedures are nested in NESTEDSUB.
The next example shows the use of global objects in WFL to provide an elementary type of IPC.
100 ?BEGIN JOB GLOBAL/DISPLAY; 110 CLASS = 0; 120 STRING MSG; 130 TASK S1, S2; 140 SUBROUTINE SUBONE; 150 BEGIN 160 WHILE S2(STATUS) ISNT SUSPENDED DO 170 WAIT(1); 180 MSG:= ACCEPT(“ENTER A MESSAGE PLEASE”); 190 S2(STATUS = ACTIVE); 200 END SUBONE; 210 SUBROUTINE SUBTWO; 220 BEGIN 230 MYSELF(STATUS = SUSPENDED); 240 DISPLAY(MSG); 250 END SUBTWO; 260 270 PROCESS SUBONE [S1]; 280 PROCESS SUBTWO [S2]; 290 300 ?END JOB
In this example, two subroutines, SUBONE and SUBTWO, are initiated as asynchronous tasks. Both subroutines fall within the scope of the string MSG, which is declared in the outer block. SUBONE waits for SUBTWO to become suspended. SUBTWO executes a statement that suspends itself. At this point, SUBONE resumes execution and assigns an operator ACCEPT message to the MSG string. SUBONE then changes the status of SUBTWO to ACTIVE. When SUBTWO resumes execution, it displays the value of the MSG string.
This is a simple example, but even in this example, it was necessary to take measures to regulate the timing of the asynchronous tasks. For example, the statement at line 180 should execute before the statement at line 240; otherwise, the DISPLAY statement at line 240 displays an empty value. This example uses assignments to the STATUS task attribute to suspend and restart execution of the asynchronous tasks. Other timing methods available in WFL include the LOCKED task attribute and various forms of the WAIT statement. These timing methods are discussed under Using Implicitly Declared Events in Using Events and Interlocks.

