Progress
Programming
Handbook
Block Context and Resource Scope
The context of some blocks also helps determine the scope of certain resources. On the other hand, the scope of other resources might have little to do with the context in which you initially define them. Scope is really the duration that a resource is available to an application. Scope can very depending on the resource and the conditions of application execution.
In general, the scope of resources created at compile time (when Progress compiles your application) is determined at compile time; the scope of resources created at run time (when Progress executes your application) is determined at run time. (See the "Compile-time Versus Run-time Execution" section.) The scope of a resource begins when the resource is instantiated (created in your application) and ends when the resource is destroyed (removed from your application).
For example, a FOR statement defines the scope of any database buffer that it implicitly defines for record reading. The scope of such a record buffer is identical to the context of the FOR block, because the buffer is deleted when the FOR block finishes with it. For example, in
p-block1.p
, the scope of the Customer buffer ends when the FOR block completes. Although the MESSAGE statement following the FOR block can access balance-sum, it can no longer access the Balance field for any record read into the Customer buffer by the FOR block.Unscoped Resources
On the other hand, this procedure fragment does not even compile, precisely because the FOR block defines the scope of FRAME A. It appears that FRAME A is defined and available in the procedure context. However, the DEFINE FRAME statement does not scope the frame that it defines. Instead, the frame is scoped by the context of its first use, in this case the FOR block. As a result, the frame is actually deleted at run time when the FOR block completes. Progress knows this and thus prevents this fragment from compiling:
The solution is to either use a FORM statement to scope the frame to the procedure block, or define a separate frame for the second reference.
Dynamic Resources
In general, dynamic resources are resources that you implicitly or explicitly create and delete at run time. Record buffers that a FOR statement implicitly defines are dynamic buffers: Progress creates them when the FOR block executes and deletes them when its execution completes. Frames scoped to a FOR block are dynamic in the same way. The whole context of a procedure is dynamic: Progress creates its local data and user interface resources when you call the procedure and deletes them when the procedure returns or otherwise goes out of scope.
However, Progress allows you to create and delete many dynamic resources explicitly. These include external procedure contexts (persistent procedures) and most user interface widgets. In general, the scope of a dynamic resource lasts from the time you create it to the time you delete it or when the Progress client session ends, which ever occurs first. When a procedure block completes execution and its context goes out of scope, this does not affect the scope of any dynamic resources that you have created in that context. The completion of the procedure can only affect whether the resources are still accessible from the context that remains.
Progress allows you to define handles to most dynamic resources. These handles are variables that point to the resources you have created. You must ensure that handles to these resources are always available to your application until you delete the resources. If you create a dynamic widget within a procedure and do not delete it before the procedure completes, the widget remains in scope within your Progress session. If you also lose the original handles to these widgets when the procedure ends, you might not be able to access them again. If you cannot access them, you cannot delete them. In effect, they become memory lost to Progress and the system (that is, a memory leak), as in
p-clock1.p
.
This example calls a procedure, get-time, to display the current time for five seconds on request. When get-time executes, it creates a new window for the clock and hides that window before returning. However, the handle to the window, clock-handle, is part of the get-time context and is lost when the procedure returns. Thus, each time get-time returns, it makes another window’s worth of memory unavailable for use until Progress exits. The correct way for get-time to manage its clock window is to use the DELETE WIDGET statement to explicitly delete the window before returning.
For more information on blocks, context, and scoping, see Block Properties." For more information on frame scope, see "Frames" For more information on managing dynamic widgets, see "Using Dynamic Widgets".
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |