DRAIN Variable, ...
When exiting a procedure, memory and any other resources aquired by
the procedure need to be released. The Drain command in conjunction
with Drain methods are used to release memory and other resources.
Any Local variables are automatically Drained when leaving a procedure.
You only need to use the Drain command when writing low level procedures
that manage memory along with the
When a program terminates
Operands to a Drain command are a list of variables whose resources are to be released. Usually operands are structures. For operands with a primitive type, only Strings use dynamically allocated memory that needs to be freed. Numeric variables and enumerations do not use dynamic memory so there is nothing to release.
Structures are drained either by invoking a Drain method as described below or automatically. Each field within a structure is individually drained. Memory used by String fields is always automatically deallocated. Fields with a numeric or an enumerated type do not need to be drained. Fields that are themselves structures are drained recursively.
If a field that is a Wizard pointer references an object it will not be automatically drained. This is when a Drain method needs to be written. When leaving a procedure, if a Drain method exists for a structure then it will automatiacally but called. Not all referenced data needs to be released, but Dynamic structures referenced by a pointer field need to be explicitly released.
Operands on a Drain (or Clean) command may be a scalar variable, array, or a Wizard pointer. A reference pointer cannot be used as an argument. The Clean operation initializes variables and is automatically applied to all Local variables when entering a method.
method DRAIN..type [pure] change [Name] Type
Any Class that declares a structure can also declare a Drain method to explicitly release memory and other resources used within the Class. When a variable with a structure type is drained and there is a Drain method coded for the structure it is automatically invoked.
Explicit calls to Drain methods generally do not need to be coded. Instead they are automatically called for Local variables when returning from a procedure or unwinding the call stack after an exception is raised.
If a Drain method is to be invoked from a pure procedure it also needs to be pure. Since releasing resources could have side effects, not all Drain methods can be pure. For example to drain a file handle you'll need to close the file; which is an I/O operation with side effects.
Should a Drain method raise an exception then it is treated as a program fault. When this happen the program will be in a corrupt state and can try to recover or terminate.
To explicitly manage memory it helps to know the life cycle of a variable.
Allocate Memory for a Local or Global variable is automatically allocated. Variables can also be dynamically allocated and referenced via a Wizard pointer. Clean Set any default values. Primitieve type with no default are set to 0 if numeric or a string is set to empty. Variables are initialized unless the default is set to "?". Transact Perform operations on the variable. Empty Variables can be reset by draining and then cleaning them. Transact Operations on a variable can resume after being emptied. Drain Deallocate memory used by the variable. A Drain method is used to drain memory held within a structure. Deallocate Deallocate the variable itself. Local and Global variables are freed by the compiler.
A Class containing a type declaration with pointers to dynamically allocated memory is typically coded with at least one initialized field serving as a "first time thru" flag. A single field can be initialized if you want to minimize overhead when cleaning a variable.
class Aggregate, &A dynamic class. Size = 0 word, &Number of elements in use. - @Root Element :Link to the root element.
Importing the generic
import Empty.Type(Aggregate) :Import the Empty..Aggregate method. import Dynamic.Type(Aggregate) :Import New..Aggrigate, Free..Aggregate, and Empty..Aggrigate methods.