Data types and Operators

Operator @ Foundation

Reference operator (unary): passing a variable by reference instead of by value.

Syntax
@<VarName>
Parameters
<VarName>
<VarName> designates a variable of any storage class, an array element or a member variable of an object.
Description

The reference operator (@) passes variables by reference to functions or procedures. Normally variables are passed by value and the receiving parameters of a function or procedure contain copies of the values of the variables. When the copy is changed within a called function or procedure, the variable in the calling function remains untouched. At the end of the called function or procedure the variable within the calling function is unchanged and the function or procedure's copy is discarded.

When a variable is passed by reference, the receiving parameter receives a reference to the variable in the calling function, instead of the copy of the value of the variable. Any change to the value is then visible in the calling function after the called routine returns. A change of the value in the called routine changes the contents of the variable in the calling function, if it is passed by reference.

With data types array and object the variable itself contains only a reference to the value. When an array or object is passed by value, the contents of the array (array elements) or of the object (member variables) can be changed in the called function. The actual contents of the variable (the reference) is not changed. Changes made to the array elements or member variables remain when the called function returns.

The reference operator always passes a variable by reference regardless of its data type or storage class. If a variable references an array, it is possible to pass one of its elements by reference. Likewise, if a variable reference an object, it is possible to pass a reference to one of its member variables. In fact, even field variables can be passed by reference. If a member variable is passed by reference it must be declared EXPORTED: and may not have the attribute READONLY.

Examples
The reference operator (@)
// In this example a UDF is written to format a character string 
// so that the first letter is uppercase and the rest of 
// the letters are lowercase. Using this UDF, the difference 
// between the passing as value and passing by reference 
// is demonstrated. 

PROCEDURE Main 
   LOCAL cName := "XBASE++" 
                                    // pass by value 
   ? UpperLower( cName )            // result: Xbase++ 
   ? cName                          // result: XBASE++ 

   UpperLower( @cName )             // pass by reference 
   ? cName                          // result: Xbase++ 

RETURN 

FUNCTION UpperLower( cString ) 
   cString := Upper( Left(cString,1) ) + ; 
              Lower( SubStr(cString,2) ) 
RETURN cString 
Passing arrays with the reference operator (@)

// This example demonstrates the difference of passing of 
// an array as value and by reference. 

PROCEDURE Main 
   LOCAL aArray := { "A", "B", "C" } 

   UserProc( aArray )               // pass by value 
   ? aArray[1]                      // result: 10 
   ? aArray[2]                      // result: 20 
   ? aArray[3]                      // result: 30 

   UserProc( @aArray )              // pass by reference 
                                    // result: 
   ? aArray                         // That was once an array 

   ? aArray[1]                      // runtime error 
RETURN 

PROCEDURE UserProc( aValue ) 
   aValue[1] := 10 
   aValue[2] := 20 
   aValue[3] := 30 
   aValue    := "That was once an array" 
RETURN 

Passing array elements by reference

// This example demonstrates the difference between passing 
// an array element by value and by reference. 

PROCEDURE Main 
   LOCAL aArray := { "A", "B", "C" } 

   Test( aArray[2] )                // pass by value 
   ? aArray[2]                      // result: B 

   Test( @aArray[2] )               // pass by reference 
   ? aArray[2]                      // result: b 
RETURN 

PROCEDURE Test( cString ) 
   cString := Lower( cString ) 
RETURN 
Feedback

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.