Strong-scoped references and containing blocks
- Last Updated: January 16, 2024
- 4 minute read
- OpenEdge
- Version 12.8
- 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.