When running your program, three methods that Rexx looks for, and runs automatically when appropriate, are INIT, UNINIT, and STRING.
Object classes can create instances. When these instances require initialization, you'll want to define an INIT method to set a particular starting value or initiate some startup processing. Rexx looks for an INIT method whenever a new object is created and runs it.
The purpose of initialization is to ensure that the instance variables are initialized correctly before using it in an operation. If an INIT method is defined, Rexx runs it after creating the instance. Any initialization arguments specified in the NEW message are passed to the INIT method, which can use them to set the initial state of object variables.
If a class overrides the INIT method it inhertits from a superclass, the new INIT method must forward the INIT message up the hierarchy, to properly initialize the instance. An example in the next section demonstrates the use of INIT.
The STRING method is a useful way to access object data and return it in string form for use by your program. When a SAY instruction is processed in Rexx, Rexx automatically sends a STRING message to the object specified in the expression. Rexx uses the STRING method of the Object class and returns a human-readable string representation for the object. For example, if you instruct Rexx to say a, and a is an array object, Rexx returns an array. You can take advantage of this automatic use of STRING by overriding Rexx's STRING method with your own, and extract the object data itself—in this case, the actual array data.
The following programs demonstrate STRING and INIT. In the first program, the Part class is created, and along with it, the two methods under discussion, STRING and INIT:
/* PARTDEF.CMD - Class and method definition file */ /* Define the Part class as a public class */ ::class part public /* Define the INIT method to initialize object variables */ ::method init expose name description number use arg name, description, number /* Define the STRING method to return a string with the part name */ ::method string expose name return "Part name:" name
In the ::CLASS directive, the keyword PUBLIC indicates that the class can be shared with other programs. The two ::METHOD directives define INIT and STRING. Whenever Rexx creates a new instance of a class, it calls the INIT method the new instance.. The sample INIT method uses an EXPOSE instruction to make the name, description, and number variables available to other methods. These exposed variables are object variables, and are associated with a single instance of a class:
The INIT method expects to be passed three arguments. The USE ARG instruction assigns these three arguments to the name, description, and number variables, respectively. Because those variables are exposed, the values are available to other methods.
The STRING method returns the string Part name:, followed by the name of a part. The STRING method does not expect any arguments. It uses the EXPOSE instruction to identify which object variables it requires. The RETURN instruction returns the result string.
The following example shows how to use the Part class:
/* USEPART.CMD - use the Part class */ myparta=.part~new("Widget","A small widge",12345) mypartb=.part~new("Framistat","Device to control frams",899) say myparta say mypartb exit ::requires partdef
The USEPART program creates two parts, which are instances of the Part class. It then displays the names of the two parts.
Rexx processes all directives before running your program. The ::REQUIRES directive indicates that the program needs access to public class definitions that are in another program. In this case, the ::REQUIRES directive refers to the PARTDEF program, which contains the Part definition.
The assignment instructions for Mypart A and Mypart B create two objects that are instances of the Part class. The objects are created by sending a NEW message to the Part class. The NEW message causes the INIT method to be invoked as part of object creation. The INIT method takes the three arguments you provide and makes them part of the object's own exclusive set of variables, called a variable pool. Each object has its own variable pool (name, description, and number).
The SAY instruction sends a STRING message to the object. In the first SAY instruction, the STRING message is sent to MypartA. The STRING method accesses the Name object variable for MypartA and returns it as part of a string. In the second SAY instruction, the STRING message is sent again, but to a different object: MypartB. Because the STRING method is invoked for MypartB, it automatically accesses the variables for MypartB. You do not need to pass the name of the object to the method in order to distinguish different sets of object variables; Rexx keeps track of them for you.
Normally, object classes can create instances but have no direct control over their deletion. Once an object is no longer referenced by any variables, Rexx automatically reclaims the storage for the old value in a process called garbage collection.
If the instance has allocated other system resources, Rexx cannot automatically release these resources because it is unaware that the instance has allocated them. An UNINIT method give an object the opportunity to perform resource cleanup before the object is reclaimed by the garbage collector.
In the following example, the value passed to text is initialized by Rexx using INIT and deleted by Rexx using UNINIT. This program makes visible Rexx's automatic invocation of INIT and UNINIT by revealing its processing on the screen using the SAY instruction:
/* UNINIT.CMD - example of UNINIT processing */ a=.scratchpad~new("Of all the things I've lost") a=.scratchpad~new("I miss my mind the most") say "Exiting program." exit ::class scratchpad ::method init expose text use arg text say "Remembering" text ::method uninit expose text say "Forgetting" text return
Whether uninitialization processing is needed depends on the circumstances, If the object only contains references to normal Rexx objects, an UNINIT method is generally not needed. If the object contains references to external system resources such as open network connections or database connections, an UNINIT method might be required to release those resources. If an object requires uninitialization, define an UNINIT method to perform the cleanup processing you require.
If an object has UNINIT an method, Rexx runs it before reclaiming the object's storage. If an instance overrides an UNINIT method of a superclass, each UNINIT method is responsible for sending the UNINIT message up the hierarchy, using the SUPERCLASS overrides, so that each inherited UNINIT method has the opportunity to run.