| **Navigation:**  [[introduction.htm|Language Reference]] > 3 - Variable Declarations > Special Data Types >====== ANY (any simple data type) ====== | [[special data types.htm|{{btn_prev_n.gif|Previous page}}]][[introduction.htm|{{btn_home_n.gif|Return to chapter overview}}]][[like inherited data type .htm|{{btn_next_n.gif|Next page}}]] | | || label **ANY** [,**DIM( )**] [,**NAME( )**] [,**EXTERNAL**] [,**DLL**] [,**STATIC**] [,**THREAD**] [,**PRIVATE**] [,**PROTECTED**] {{blk2blue.jpg|blk2blue.jpg}} | **ANY** | A variable that may contain any value (numeric or string) or a reference to any simple data type. | | **DIM** | Dimension the variable as an array. | | **NAME** | Specify an alternate, "external" name for the field. | | **EXTERNAL** | Specify the variable is defined, and its memory is allocated, in an external library. Not valid within FILE, QUEUE, or GROUP declarations. | | **DLL** | Specify the variable is defined in a .DLL. This is required in addition to the EXTERNAL attribute. | | **STATIC** | Specify the variable's memory is permanently allocated. | | **THREAD** | Specify memory for the variable is allocated once for each execution thread. Also implicitly adds the STATIC attribute on Procedure Local data. | | **PRIVATE** | Specify the variable is not visible outside the module containing the CLASS methods. Valid only in a CLASS. | | **PROTECTED** | Specify the variable is not visible outside base CLASS and derived CLASS methods. Valid only in a CLASS. | **ANY** declares a variable of a reference type which points to an internal RTL data structure. That structure can hold values of any numeric or string type, and references to any simple data type and to GROUPs. This allows an ANY variable to be used as a "generic" data type. An ANY variable may be declared within a CLASS, GROUP, or QUEUE structure, and may not be declared within a FILE structure. If an ANY variable is declared outside a GROUP or QUEUE structure it is initialized to a NULL reference. Such ANY variables must be declared without the AUTO attribute. When an ANY variable is the destination of a simple assignment statement (destination = source) and it contains a NULL reference, the RTL first creates an internal object of a default type and sets the ANY variable to referencethat object, and then performs the assignment of the value of the source expression to that internal object. When an ANY variable is the destination of a simple assignment statement and it contains a non-NULL reference, the assignment changes value of a variable, or a structure pointed ay by that reference. When an ANY variable is the destination of a reference assignment statement (destination &= source), the RTL disposes its previous internal data and replaces it with a new object which holds a reference to the source variable. If the source of a reference assignment is NULL, the RTL disposes the previous internal data of the ANY variable from the left side, and then sets the ANY to a NULL reference. \\ When an ANY variable is the parameter of the CLEAR statement, the data it points to is cleared. An ANY can be named in the USE attribute of any control in a window or report, provided that the ANY contains a non-NULL reference. If an ANY variable named in the USE attribute has not been set to reference to some variable declared in the program, i.e. it references a default object created by the RTL, the program should not perform a reference assignment with such ANY as a destination. (See the [[reference variables.htm#refvardec|rules]] of reference variables as USE variables) \\ You cannot pass an ANY variable as a variable-parameter (by address) unless the calling procedure is prototyped to receive an untyped variable parameter (*?). If an ANY variable passed as a parameter of *? type has not been set to reference to some variable declared in the program, i.e. it references a default object created by the RTL, the program should not perform a reference assignment with such ANY as a destination, for example, from other threads, until the Procedure returns. When an ANY variable is declared in a QUEUE structure, there are some special considerations that must be followed. This is due to the internal representation of an ANY and its polymorphic characteristics. __Use of CLEAR() and reference assignments with QUEUE entries.__ Once an ANY variable in a QUEUE has been assigned a value, another simple assignment statement will assign a new value to the ANY. This means the previous value is replaced by the new value. If the first value has already been added to the QUEUE, then that entry will "point at" a value that no longer exists. Once an ANY variable in a QUEUE has been reference assigned a variable (AnyVar &= SomeVariable), another reference assignment statement will assign a new variable to the ANY. This means the previous "pointer" is disposed of and replaced by the new "pointer." If the first reference has already been added to the QUEUE, then that entry will "point at" a "pointer" that no longer exists. Therefore, Queue fields of type ANY must be set to NULLs by executing the CLEAR statement with the QUEUE record structure itself as parameter, i.e. the program must execute CLEAR(Queue), before setting new values of queue field of type ANY for the next ADD() or PUT(). This is because CLEAR for QUEUEs and GROUPs are not applied recursively to the data pointed at from fields of reference types. Therefore, CLEAR(queue) just sets fields of type ANY to NULLs without disposing of their internal data. In addition, you need to reference assign a NULL to all queue fields of type ANY (Queue.AnyField &= NULL), prior to deleting the QUEUE entry, in order to avoid memory leaks. **Example:** **MyQueue  QUEUE** **AnyField ****ANY****                     !Declare a variable to contain any value** **Type      STRING(1)** **         END** **DueDate  DATE                     !Declare a date field** ** CODE** ** MyQueue.AnyField = 'SoftVelocity'!Assign a string value** ** MyQueue.Type = 'S'               !Flag data type** ** ADD(MyQueue) ** ** CLEAR(MyQueue)                   !Clear the reference** ** MyQueue.AnyField &= DueDate      !Assign a Reference to a DATE** ** MyQueue.Type = 'R'               !Flag data type** ** ADD(MyQueue) ** ** LOOP X# = RECORDS(MyQueue) TO 1 BY -1 !Process the QUEUE** **  GET(MyQueue,X#)** **  ASSERT(~ERRORCODE())** **  CASE MyQueue.Type** **  OF 'S'** **   DO StringRoutine** **  OF 'R'** **   DO ReferenceRoutine** **  END** **  MyQueue.AnyField &= NULL         !Reference assign NULL before deleting** **  DELETE(MyQueue)** **  ASSERT(~ERRORCODE())** ** END** **Use of ANY in CLASS/GROUP definitions.** If you do a reference assignment, or assign a value to an ANY that is a member of a CLASS or GROUP, you must clear the reference //before// destroying the class, otherwise the memory allocated by the reference assignment will not be freed. **Example:** **AClass CLASS** **AnyVar   ANY,PRIVATE** **AMethod  PROCEDURE(FILE f)** **Destruct PROCEDURE()** **       END** **TextFile FILE,DRIVER('ASCII')** **          RECORD** **Line       STRING(255)** **          END** **         END** **  ** **  CODE** **    AClass.AMethod(TextFile)** **AClass.AMethod PROCEDURE(FILE TextFile)** **AGroup &GROUP** **  CODE** **    AGroup &= TextFile{PROP:Record}** **    SELF.AnyVar &= WHAT(AGroup, 1)** **    ** **AClass.Destruct PROCEDURE()** **  CODE** **    SELF.AnyVar &= NULL  !Without this line the program will leak memory** {{newcnet.jpg|NewCNet.jpg}} The ANY data type is represented with the special dedicated **Clarion.ClaAny** class. The ANY data type of Clarion .NET is compatible with the ANY data type of the WIN 32 Clarion. Remarks: 1. Unlike WIN32 Clarion, you can use the type ANY in a NEW statement. 2. You can't assign a reference to array to an ANY variable **See Also:** [[simple assignments.htm|Simple Assignment Statements]] [[reference assignments.htm|Reference Assignment Statements]]