The NEW command "stacks" copies of local variables and reinitializes those variables. An explicit or implicit QUIT from a DO, XECUTE or extrinsic function "unstacks" the NEWed variables, that is, restores the variable to the stacked value. A NEW lasts only while the current scope of execution is active.
The format of the NEW command is:
N[EW][:tvexpr] [[(]lvn[,...][)][,...]]
The optional truth-valued expression immediately following the command is a command postconditional that controls whether or not GT.M executes the command.
NEW arguments are unsubscripted local variable names; NEW affects not only the variable specified in the argument, but also all variables descended from that variable.
When an undefined variable is NEWed, the fact that it is undefined is "stacked", and when leaving the current scope, it returns to being undefined, that is, the variable is implicitly KILLed during transfer of control.
Without an argument GT.M NEWs all currently existing local variables; in this case, at least two (2) spaces must follow the NEW to separate it from the next command on the line.
For the scope of the NEW, a NEW of a name suspends its alias association. The association is restored when the scope of the New ends. The array remains in existence - it can be modified through other alias variables with which it is associated and which remain in scope. If none of its alias variables is in scope, the array remains intact and again becomes visible when the scope is restored.
When a NEW argument is enclosed in parentheses, that NEW is considered "exclusive". An exclusive NEW creates a fresh data environment and effectively aliases the excluded variables with their original copies. This technique tends to improve performance and meets the M standard. However, it has two implications: The alias operation KILL *, with no arguments, or naming an exclusively NEW'd variable, acts as a KILL in the current scope (has the same effect as a non-alias KILL), and ZWRITE, ZSHOW "V", $ZDATA() report any exclusively NEW'd variable as an alias. Refer to the section on the KILL command for a description of alternative behaviors for the interaction of KILL and exclusive NEW. For a comprehensive discussion on alias variables, refer to “Alias Variables Extensions”.
When the flow of execution terminates the scope of an argumentless or an exclusive NEW, GT.M restores all stacked variables to their previous values, and deletes all other local variables.
The intrinsic special variables $ESTACK, $ETRAP, $ZGBLDIR, and $ZYERROR can be an explicit argument of a NEW.For more information, refer to Chapter 8: “Intrinsic Special Variables”.
The intrinsic special variable $ZTRAP can also be an explicit argument of a NEW; this stacks the current value of $ZTRAP and assigns $ZTRAP a null value ($ZTRAP="").
An indirection operator and an expression atom evaluating to a list of one or more NEW arguments form a legal argument for a NEW.
The NEW command provides a means of confining the scope of local variables. NEW operates only on unsubscripted local names and acts on the entire named array.
Example:
NEW1; Set A(1)=1,B=4,C=5 Write !,"VARIABLES BEFORE NEW:",! ZWRite Do LABEL Write !,"VARIABLES AFTER RETURN:",! ZWRite Quit LABEL New A Set C=7 Write !,"VARIABLES AFTER NEW:",! ZWRite Quit
Produces the results:
VARIABLES BEFORE NEW: A(1)=1 B=4 C=5 VARIABLES AFTER NEW: B=4 C=7 VARIABLES AFTER RETURN: A(1)=1 B=4 C=7
Example:
NEW2; Set (A,B,C,D)="TEST" Do LABEL Write !,"VARIABLES AFTER RETURN:",! ZWRite Quit LABEL New (B,C) SET (A,B,Z)="NEW" Write !,"VARIABLES AFTER EXCLUSIVE NEW:",! ZWRite Quit
Produces the results:
VARIABLES AFTER EXCLUSIVE NEW: A="NEW" B="NEW" C="TEST" Z="NEW" VARIABLES AFTER RETURN: A="TEST" B="NEW" C="TEST" D="TEST"
Example:
/usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^stackalias stackalias ; Demonstrate New with alias ZPrint ; Print this program Set A=1,*B=A,*C(2)=A ; Create some aliases Write "------------",! Write "ZWRite in the caller before subprogram",! ZWRite Do S1 ; Call a subprogram Write "------------",! Write "ZWRite in the caller after subprogram - A association is restored",! ZWRite Quit ; S1 ; Subprogram New A Set A="I am not an alias",B="I am an alias" Write "------------",! Write "ZWRite in the subprogram with new A and modified B",! ZWRite Quit ------------ ZWRite in the caller before subprogram A=1 ;* *B=A C=3 *C(2)=A D=4 ------------ ZWRite in the subprogram with new A and modified B A="I am not an alias" B="I am an alias" ;* C=3 *C(2)=B D=4 ------------ ZWRite in the caller after subprogram - A association is restored A="I am an alias" ;* *B=A C=3 *C(2)=A D=4
The following is essentially the same as the prior example but using an exclusive NEW:
$ /usr/lib/fis-gtm/V5.4-002B_x86/gtm -run ^stackalias1 stackalias1 ; Demonstrate New with alias ZPrint ; Print this program Set A=1,*B=A,*C(2)=A ; Create some aliases Write "------------",! Write "ZWRite in the caller before subprogram",! ZWRite Do S1 ; Call a subprogram Write "------------",! Write "ZWRite in the caller after subprogram - A association is restored",! ZWRite Quit ; S1 ; Subprogram New (B) Set A="I am not an alias",B="I am an alias" Write "------------",! Write "ZWRite in the subprogram - Notice B is flagged as an alias",! ZWRite Quit ------------ ZWRite in the caller before subprogram A=1 ;* *B=A C=3 *C(2)=A D=4 ------------ ZWRite in the subprogram - Notice B is flagged as an alias A="I am not an alias" B="I am an alias" ;* ------------ ZWRite in the caller after subprogram - A association is restored A="I am an alias" ;* *B=A C=3 *C(2)=A D=4
An exclusive New can create a scope in which only one association between a name or an lvn and an array may be visible. In this case, ZWRITE nevertheless shows the existence of an alias, even when that array is accessible from only one name or lvn.