Statement LOCAL Foundation

Declaration and initialization of LOCAL variables.

LOCAL <VarName> [[:= <Expression>], ... ]
LOCAL <VarName> AS STRUCTURE <StructName>
<VarName> designates the name of a LOCAL variable. If the array element operator [] immediately follows <VarName>, an array is assigned to the variable. The array can be dimensioned by specifying the number of array elements, as in:
LOCAL <aArray>[<nDimension1>, <nDimension2>,...] // or 
LOCAL <aArray>[<nDimension1>][<nDimension2>]... 
If an array is declared in this form, all array elements contain the value NIL. The size of an array is unlimited in the number of elements and in the number of dimensions.
Note: other than by the declaration of PRIVATE or PUBLIC variables, the variable name <VarName> cannot be generated with the macro operator (&) at runtime. <VarName> must be known at compile time.
<Expression> is any legal expression whose value is assigned to the variable using the inline assignment operator (:=). If no assignment is made, the variable is initialized with the value NIL. If the variable was initialized as an array in the above described form, no assignment can be made.
Several variables may be declared as long as the variable names, including assignment, are separated by commas.
If the AS STRUCTURE syntax is used to declare and initialize a LOCAL variable, an instance of a structure <StructName> is created. See the STRUCTURE statement for further information.

The LOCAL statement declares memory variables of storage class LOCAL. Memory variables exist only in memory and are released after the end of a program, as opposed to field variables that are stored on disk. Storage classes define the lifetime and the visibility of variables. LOCAL variables are visible only within the function or procedure in which they are declared. They are released as soon as the function or procedure ends. Since their visibility is limited to the declaring function, they are not visible in any called functions or procedures. This also pertains to instances when a function calls itself (recursion). LOCAL variables are redeclared and initialized with each call of a function or procedure.

The LOCAL statement must precede all executable statements in a function or procedure, including the statements PRIVATE, PUBLIC and PARAMETERS. The variable name <VarName> can occur only once within a function. This includes variables which are declared as STATIC or MEMVAR. If a PRIVATE or PUBLIC variable of the name <VarName> already exists in a function, the PRIVATE or PUBLIC variable is "hidden" and is no longer visible within the function or procedure in which the LOCAL variable is declared.

The length of a variable name is unlimited, but only the first 255 characters are significant. A variable name consists of alphanumeric characters, and the first character may not be numeric. The underscore (_) is permitted as a special character.

A LOCAL variable can be initialized with the declaration, meaning the value of any legal expression may be assigned to it using the inline assignment operator (:=), or it can be initialized by use of the array element operator ([]) as an array with any dimension and size you want.

By using the AS STRUCTURE syntax, a LOCAL variable can be initialized with a structure instance. This instance can then be accessed using the LOCAL reference, for example, for assigning values to structure members or for passing the stucture to an API function via the EXTERN command. See the STRUCTURE statement for more information.

If no assignment is made, LOCAL variables have the value NIL after declaration. When they are initialized as an array, no further assignment is possible and all array elements contain the value NIL.

The formal parameters defined by the declaration of a user-defined function or procedure as a list in parentheses are LOCAL variables (see statements FUNCTION and PROCEDURE).

LOCAL variables normally have the same lifetime as the function in which they are declared. However, they can also exist after a function ends if they are used in a code block defined in the declared function which is then returned from the function. In this case, a LOCAL variable exists within the code block and is detached from the declaring function (a detached local).

LOCAL variables cannot be saved in a file with the SAVE command. This can only be done with PRIVATE and PUBLIC variables.

The macro operator (&) cannot compile an expression containing a character string declared as a LOCAL variable. The reason is that LOCAL variables are resolved at compile time and their symbolic names do not exist at runtime.

The data type of LOCAL variables can be determined only with the function Valtype() and not with the function Type(). The reason is that the function Type() uses the macro operator in order to determine the data type of a variable or an expression. A character string must always be passed to the function Type(). Valtype() establishes the data type of a value.

In order to be able to track LOCAL variables in the debugger, the source code files (PRG files) must be compiled with the /B compiler switch so that the names of the LOCAL variables remain available as debug information.

LOCAL variable declaration and usage
// The example shows the different possibilities of the LOCAL 
// statement. LOCAL variables with various data types are 
// declared and initialized. The function SaveCursor() 
// illustrates the use of 'detached LOCALs'. 

   LOCAL cString := "Xbase++", dDate := Date() 
   LOCAL nNumber := 55       , lLogic:= .T. 
   LOCAL aArray[10]          , bBlock 

   AFill( aArray, "Xbase++" )     // fills array 
   AEval( aArray, {|c| QOut(c)} ) // outputs elements 
   Inkey(0)                       // wait for keystroke 

   bBlock := SaveCursor()         // code block with detached LOCALs 
                                  // saves cursor position 

   ?? Row()                       // Result: 0 

   ? cString 
   ? dDate 
   ? nNumber 
   ? lLogic 

   ?? Row()                       // Result: 4 

   Eval( bBlock )                 // restores cursor position 

   ?? Row()                       // Result: 0 


FUNCTION SaveCursor()             // saves position of the cursor 
   LOCAL nRow := Row()            // row 
   LOCAL nCol := Col()            // column 

RETURN {|| SetPos( nRow, nCol ) } // stores position plus 
                                  // function call in code block, 
                                  // nRow and nCol are detached 
                                  // LOCALs 

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.