The part of the program to which a name applies is called the scope of the declaration of that name. In most cases, the scope of the declaration of a name is determined entirely by the position where the name is declared within the program. Implicit declarations are treated as if the name were declared in a DECLARE statement immediately following the PROCEDURE statement of the external procedure.
It is not necessary for a name to have the same meaning throughout a program. A name explicitly declared within a block has a meaning only within that block. Outside the block, the name is unknown unless the same name has also been declared in the outer block. Each declaration of the name establishes a scope and in this case, the name in the outer block refers to a different data item. This enables you to specify local definitions and, hence, to write procedures or begin-blocks without knowing all the names used in other parts of the program.
In the following example, the output for A is actually C.A, which is 2. The output for B is 1, as declared in procedure X.
X: proc options(main);
dcl (A,B) char(1) init('1');
call Y;
return;
Y: proc;
dcl 1 C,
3 A char(1) init('2');
put data(A,B);
return;
end Y;
end X;
Thus, for nested procedures, PL/I uses the variable declared within the current block before using any variables that are declared in containing blocks.
In order to understand the scope of the declaration of a name, you must understand the terms contained in and internal to.
All of the text of a block, from the PACKAGE, PROCEDURE, or BEGIN statement through the corresponding END statement (including condition prefixes of BEGIN, PACKAGE, and PROCEDURE statements), is said to be contained in that block. However, the labels of the BEGIN or PROCEDURE statement heading the block, as well as the labels of any ENTRY statements that apply to the block, are not contained in that block. Nested blocks are contained in the block in which they appear.
Text that is contained in a block, but not contained in any other block nested within it, is said to be internal to that block. Entry names of a procedure (and labels of a BEGIN statement) are not contained in that block. Consequently, they are internal to the containing block. Entry names of an external procedure are treated as if they were external to the external procedure.
Figure 7 illustrates the scopes of data declarations.
The brackets to the left indicate the block structure; the brackets to the right show the scope of each declaration of a name. The scopes of the two declarations of Q and R are shown as Q and Q' and R and R'.
Note that X and Y are visible to all of the procedures contained in the package.
Figure 8 illustrates the scopes of entry constant and statement label declarations.
Figure 8 shows two external procedures, A and E.