Strong-scoped references and containing blocks
- Last Updated: March 30, 2020
- 4 minute read
- OpenEdge
- Version 12.2
- Documentation
Record Buffer Rule 5: If you have a strong-scoped reference to a buffer, you cannot have a free reference that raises the scope to any containing block.
The whole point of using a strong-scoping form, such
as a DO FOR block, is to force the buffer scope
to that block and nowhere else. If the AVM encounters some other
statement (such as a FIND statement) outside the
strong-scoped block that forces it to try to scope the buffer higher
than the strong scope, it cannot do this because this violates the
strong-scoped reference. For example:
|
If you try to run this procedure you get the error shown in the following figure.

Remember this distinction between Rule 1 and Rule 5. Rule 1 says that strong- and weak-scoped references in separate blocks are self-contained, so it is legal to have multiple blocks in a procedure that scope the same buffer to the block. Rule 5 tells you that it is not legal to have some other reference to the buffer that would force the scope to be higher than any of the strong-scoped references to it.
Here are some additional examples that illustrate how these rules interact:
|
This procedure displays all the Customers with CreditLimits over 80000, saving off the Customer number of the highest one. The following figure shows the first result.

It then finds that Customer again with the highest CreditLimit and redisplays it with some more fields, as shown in the following figure.

This example illustrates that it is valid to have a weak-scoped
block enclosed in a strong-scoped block. The AVM raises the scope
of the Customer buffer to the outer DO FOR block.
This allows you to reference the buffer elsewhere in the DO
FOR block, such as the FIND statement.
The FIND statement raises the scope of the buffer
to the DO FOR block, the nearest containing block with
block-scoping properties.
This example illustrates raising the buffer scope:
|
As it processes the procedure, the AVM encounters the FIND statement
and tentatively scopes the Customer buffer
to the REPEAT block. The REPEAT block
by itself does not force a buffer scope without a FOR phrase
attached to it but it does have the record-scoping property, so
it is the nearest containing block for the FIND statement.
This block cycles through Customers in Name order
and leaves the block when it gets to the first one starting with
D. But after that block ends, the AVM finds a free reference to
the Customer buffer in the DISPLAY statement.
This forces the AVM to raise the scope of the buffer outside the REPEAT block. Since
there is no available enclosing block to scope the buffer to, the
AVM scopes it to the procedure. Thus, the Customer buffer from
the REPEAT block is available after that block
ends to display fields from the record, as shown in the following
figure.

This next procedure has two free references, each within its
own REPEAT block:
|
As before, the AVM initially scopes the buffer to the first REPEAT block.
But on encountering another FIND statement within
another REPEAT block, the AVM must raise the scope
to the entire procedure. The first block cycles through Customers until
it finds and displays the first one whose name begins with D, and
then leaves the block. Because the buffer is scoped to the entire
procedure, the FIND statement inside the second REPEAT block
starts up where the first one ended, and continues reading Customers until
it gets to the first one beginning with E. The following figure
shows the result.

This is a very important aspect of buffer scoping. Not only are
both blocks using the same buffer, they are also using the same
index cursor on that buffer. This is different from the earlier
examples where multiple strong- or weak-scoped blocks scope the
buffer independently. In these cases, each block uses a separate
index cursor, so a second DO FOR or FOR
EACH starts fresh back at the beginning of the record set.
The difference is that the FIND statements inside
these REPEAT blocks are free references, so they
force the AVM to go up to an enclosing block that encompasses all
the free references.