Show/Hide Toolbars



Declare and initialize local variables and arrays.



[STATIC] LOCAL <idVar> [:= <uValue>] [,...] [AS | IS <idType>] [, ...]
[STATIC] LOCAL DIM <ArraySpec> [, ...] AS | IS <idType> [, ...]
[STATIC] LOCAL <ArraySpec> [, ...] [AS ARRAY] [, ...]
LOCAL ARRAY <arrayName> ( <nRows> [, <nColumns>] ) [, <arrayName> ( <nRows> [, <nColumns>] ) ]     // FoxPro dialect only
LOCAL ARRAY <arrayName> [ <nRows> [, <nColumns>] ] [, <arrayName> [ <nRows> [, <nColumns>] ] ]     // FoxPro dialect only


Note: The LOCAL statement is shown using several syntax diagrams for convenience.  You can declare variables, dynamic arrays, and dimensioned arrays using a single LOCAL statement if each definition is separated by a comma.



STATICCauses the local variable to retain its value across invocations of the declaring entity but does not affect its visibility.



<idVar>A valid identifier name for the local variable to declare.


<uValue>The initial value to assign to the variable.
For LOCAL, this can be any valid expression.
For STATIC LOCAL, this value can be a literal representation of one of the data types listed below or a simple expression involving only operators, literals, and DEFINE constants; however, more complicated expressions (including class instantiation) are not allowed.
Note:  Although <uValue> can be a literal array, it must be one-dimensional.  Multi-dimensional literal arrays are not allowed.  For example, {1, 2, 3} is allowed, but {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} is not.
Note:  Although the Chr() function cannot be used in <uValue>, the _Chr() operator can.   _Chr() is otherwise identical in functionality to Chr().
If <uValue> is not specified, the initial value of the variable depends on the data type you declare (e.g., NIL if you do not use strong typing, 0 for AS INT, etc.)


DIM <ArraySpec>The specification for a dimensioned array to declare.


<ArraySpec>The specification for a dynamic array to declare.
In both cases, <ArraySpec> is one of the following:
<idArray>[<nElements>, <nElements>, <nElements>]
All dimensions except the first are optional.
<idArray> is a valid identifier name for the array to declare.  For dynamic arrays, array elements are initialized to NIL.  For dimensioned arrays, the initial value of the elements depends on the data type as explained above for <uValue>.
<nElements> defines the number of elements in a particular dimension of an array.  The number of dimensions is determined by how many <nElements> arguments you specify.
<nElements> can be a literal numeric representation or a simple numeric expression involving only operators, literals, and DEFINE constants; however, more complicated expressions (such as function calls) are not allowed.


AS <idType>Specifies the data type.  If omitted, then depending on the compiler options the type will be either USUAL or determined by the compiler.




IS <idType>Specifies a structure data type in which the memory needed to hold the structure is allocated on the stack (<idStructure> is the only <idType> allowed with the IS keyword.) See the VOSTRUCT entry in this guide for more information on data structure memory allocation.


AS ARRAYFor dynamic array declarations, specifies the data type of the entire array.


<arrayName>Variable name of array . The array will have the dimensions as declared with <nRows> and <nColumns>. The array may be declared with parentheses as delimiters but also with square brackets.
We recommend the use of square brackets.



LOCAL is a declaration statement that declares one or more variables or arrays as local to the current routine (i.e., function, method, or procedure).  Like other variable declaration statements (such as FIELD and MEMVAR), you must place LOCAL statements before any executable statements (including PRIVATE, PUBLIC, and PARAMETERS) in the routine you are defining.


Local variable declarations hide all inherited private variables, visible public variables, instance variables, global variables, and constants with the same name.  The search order for a variable name is as follows:

1.        LOCALs, local parameters, MEMVARs, and FIELDs

2.        SELF instance variables (i.e., without <idObject>:  prefix in class methods)

3.        GLOBALs and DEFINEs


A LOCAL statement that declares a variable name which is already declared within the same routine (with FIELD, LOCAL, or MEMVAR) causes a compiler error.


Local variables are visible only within the current routine, and unlike private variables, are not visible within invoked routines.  If a routine is invoked recursively, each recursive activation creates a new set of local variables.


Unless you specify the STATIC keyword, local variables are created automatically each time the routine in which they were declared begins executing.  They continue to exist and retain their values until the declaring routine returns control to the routine that invoked it.


The STATIC keyword serves as a lifetime modifier for a local variable, preventing the variable from being released from memory when the creating entity returns to its calling routine.


Important! When an application containing static variable declarations is invoked, the variables are created and initialized before the beginning of program execution.  Thus, initial values are assigned only once per application run, not each time the creator is called.



Local parameters: The FUNCTION, METHOD, and PROCEDURE statements allow you to declare a list of local parameters enclosed in parentheses following the entity name.  For example:


FUNCTION <idFunction>(<idParamList>)


Exporting locals through code blocks: When you create a code block, you can access local variables defined in the creating entity within the code block definition without passing them as parameters (because local variables are visible to the code block).  This, along with the fact that you can pass a code block as a parameter, allows you to export local variables.  For example:


  cbAdd := {|nValue| nValue + nVar}
  ? NextFunc(cbAdd)     // Result:  210
FUNCTION NextFunc(cbAddEmUp)
  RETURN EVAL(cbAddEmUp, 200)


When the code block is evaluated in NextFunc(), nVar, which is local to function One(), becomes visible even though it is not passed directly as a parameter.


Macro expressions: You cannot refer to local variables within macro variables and expressions.  If you refer to a local variable within a macro variable, a private or public variable with the same name will be referenced instead.  If no such variable exists, a runtime error will be raised.

Type of a local variable: Since Type() uses the macro operator (&) to evaluate its argument, you cannot use it to determine the type of a local variable or an expression containing a local variable reference.  You can, however, use ValType() which evaluates its argument and returns the type of the return value

Memory files: You cannot SAVE or RESTORE local variables.



The following example declares two local arrays and two local variables:


LOCAL aArray1[20, 10], aArray2[20][10], var1, var2


This example declares two local variables with initializers.  The first is initialized to a date value and the second to an array:


LOCAL dWhen := TODAY()
LOCAL aVegies := {"Tomato", "Chickadee", "Butterbean"}


In this example, the variable x and the dimensioned array z are typed as INT, while the variables cName and cAddr are typed as STRING:


LOCAL x, DIM z[100] AS INT, cName, cAddr AS STRING


The next example declares static variables both with and without initializers:


STATIC LOCAL aArray1[20, 10], aArray2[20][10]
STATIC LOCAL cString := "my string", var
STATIC LOCAL aArray := {1, 2, 3}


Here a static variable is manipulated within a function.  In this example, a count variable increments itself each time the function is called:


FUNCTION MyCounter(nNewValue)
                 // Initial value assigned once
 STATIC LOCAL nCounter := 0
 IF nNewValue != NIL
                 // New value for nCounter
 nCounter := nNewValue
                 // Increment nCounter
 RETURN nCounter


See Also