Try OpenEdge Now
skip to main content
ABL Essentials
Procedure Blocks and Data Access : Procedure block scoping
 

Procedure block scoping

Scope is the duration that a resource such as a variable or a button is available to an application. Blocks determine the scope of the resources defined within them.
This section describes some of the basic rules pertaining to procedures and scope. Variable and object definitions are always scoped to the procedure they are defined in. In this book, the word object refers to the various kinds of visual controls you can define, such as buttons and browses, as well as queries and other things you'll work with later.
You wrote some variable definitions in your very first procedure. For example:
/* h-CustSample.p -- shows a few things about ABL */

DEFINE VARIABLE cMonthList AS CHARACTER NO-UNDO
  INITIAL "JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC".
DEFINE VARIABLE iDays   AS INTEGER   NO-UNDO. /* used in calcDays proc */
ABL scopes those variables to the procedure. They are available everywhere within that main procedure block and every block it contains, including any internal procedures and triggers. For instance, you could write a line of code inside the calcDays internal procedure that is part of h-CustSample.p, and that code would compile and execute successfully. It would use the same copy of the variable that the enclosing procedure uses.
If you define variables or other objects within an internal procedure, then they are scoped to that internal procedure only and are not available elsewhere in the external procedure that contains it. You can use the same variable name both in an internal procedure and in its containing external procedure. You'll get a second variable with the same name but a distinct storage location in memory and therefore its own distinct value.
Here are a few simple examples to illustrate this point. In the first, the variable cVar is defined in the external procedure and therefore available, not only within it, but within the internal procedure subproc as well:
/* mainproc.p */
/* This is scoped to the whole external procedure. */
DEFINE VARIABLE cVar AS CHARACTER NO-UNDO INITIAL "Mainproc".

RUN subproc.

PROCEDURE subproc:
  DISPLAY cVar.
END PROCEDURE.
If you run this procedure, you see the value the variable was given in mainproc as displayed from the contained procedure subproc, as shown in the following figure.
Figure 2. Result of variable defined in main procedure only
By contrast, if you define cVar in the subprocedure as well, it can have its own value:
/* mainproc.p */

/* This is scoped to the whole external procedure. */
DEFINE VARIABLE cVar AS CHARACTER NO-UNDO INITIAL "Mainproc".

RUN subproc.
DISPLAY cVar.

PROCEDURE subproc:
  DEFINE VARIABLE cVar AS CHARACTER NO-UNDO.
  cVar = "Subproc".
END PROCEDURE.
Run this code and you get the same result you did before, as shown in in the following figure.
Figure 3. Result of variable defined in both main and subprocedures
You assign a different value to the variable in the subprocedure, but because the subprocedure has its own copy of the variable, that value exists only within the subprocedure. Back in the main procedure, the value Mainproc is not overwritten even after the subprocedure call.
As a third example, if you define a new variable in the internal procedure, it won't be available in the main procedure at all:
/* mainproc.p */
/* This is scoped to the whole external procedure. */
DEFINE VARIABLE cVar AS CHARACTER NO-UNDO INITIAL "Mainproc".

RUN subproc.
DISPLAY cVar cSubVar.

PROCEDURE subproc:
  DEFINE VARIABLE cVar AS CHARACTER NO-UNDO.
  DEFINE VARIABLE cSubVar AS CHARACTER NO-UNDO.

  ASSIGN
    cVar    = "Subproc"
    cSubVar = "LocalVal".
END PROCEDURE.
Here cSubVar is defined only in the internal procedure, so when you try to display it from the main procedure block you get an error, as shown in the following figure.
Figure 4. Result of variable defined in the subprocedure only
The main procedure block where the DISPLAY statement is located never heard of cSubVar, because it's defined with the subproc internal procedure. Even though it's defined within the same source procedure file, it's as separate from the main procedure block as it would be if it were in a completely separate external procedure file.