Logo

Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.

LParameters, Parameters, SET UDFPARMS, Set(“UDFParms”)

PARAMETERS and LPARAMETERS specify the formal parameters for a procedure or function. SET UDFPARMS determines whether the default for parameters sent to functions is passing by value or by reference. (For basics on parameter passing, see “Pass the Parameters, Please” in “Xbase Xplained.”)

Usage

LPARAMETERS Parameter1 [ AS Type1 [ OF ClassLib1 ] ]
            [, Parameter 2 [ AS Type2 [ OF ClassLib2 ] ] [, ... ]
PARAMETERS Parameter1 [ AS Type1 [ OF ClassLib1 ] ]
           [, Parameter 2 [ AS Type2 [ OF ClassLib2 ] ] [, ... ]

Each of these commands accepts a comma-delimited list of variable names that receive the parameters when the routine is called. These variables are also known as “formal parameters.” (The values passed by the calling routine are known as “actual parameters.”) Be aware that in versions prior to VFP 7, you could omit the comma between the formal parameters without a problem. That’s no longer true—the comma is required in VFP 7 and later.

Beginning in VFP 7, you can specify the expected type of each parameter along with its name. For code meant to run only in VFP apps, this serves more as documentation than anything else, because the types you specify aren’t enforced. However, IntelliSense does pay attention, so when you specify a parameter as being an object of a particular class, you enable List Members functionality for that parameter. In addition, for parameters to methods of COM objects, specifying the type allows a type library to be built, and COM enforces those types when the object is instantiated and called.

VFP 7 mishandles multi-line parameter statements for methods. When you create a subclass and one of the methods of the original class has a multi-line parameter list, the parameter list for that method of the subclass all appears on a single line. In VFP 6, any tabs or spaces that were placed at the beginning of the second and subsequent lines are removed; in VFP 7, those tabs and spaces are copied into the single line.

In addition, under some circumstances in the original release of VFP 7, if the parameter statement isn't the first in the method, it doesn't get copied to the same method in a subclass. This bug is fixed in Service Pack 1.

LPARAMETERS or PARAMETERS must be the first executable statement in the routine. This means the only things that can be put between the FUNCTION or PROCEDURE line and the parameter declaration are comments and compile-time directives, such as #INCLUDE and #DEFINE.

LPARAMETERS creates the parameters as local variables, while PARAMETERS makes them private. We strongly recommend you use LPARAMETERS unless you have a specific reason not to. You can only use one or the other in a given routine. As soon as FoxPro finds a parameter declaration, it rejects any other.

You can also list parameters as part of the function or procedure heading. Parameters created that way are local. See the comments in the example below for an example of how to do this.

Example

FUNCTION OneName
* Take a first name and last name and return one name.
* If either parameter is missing or is the wrong type,
* return the empty string.
* The heading could be:
*    FUNCTION OneName(cFirst, cLast)
* instead, and the LPARAMETERS line omitted,
* with the same effect.

LPARAMETERS cFirst, cLast

* Test parameters.
IF PCOUNT() < 2
   RETURN ""
ENDIF

IF TYPE("cFirst") <> "C"
   RETURN ""
ENDIF

IF TYPE("cLast") <> "C"
   RETURN ""
ENDIF

RETURN TRIM(cFirst) + " " + TRIM(cLast)

Usage

SET UDFPARMS TO REFERENCE | VALUE
cParmSetting = SET( "UDFPARMS" )

Parameters can be passed either by reference or by value. When passed by reference, changes to the formal parameter also change the actual parameter passed. When parameters are passed by value, changes to the formal parameter in the routine do not affect the actual parameter. Another way to look at this is that a parameter by reference means that the parameter is not a separate memory variable, but just a placeholder (sort of an alias) within the routine, and all use of that parameter within the procedure refers back to the original variable. When passing parameters by value, on the other hand, the original memory variable is shielded, and only the value is transferred to the new routine, which must create a new memory variable to hold this value.

In order to pass the entire contents of an array (rather than just the first element), it must be passed by reference.

In FoxPro, by default, parameters are passed to procedures by reference and to functions by value. (But it’s the call that determines whether you have a procedure or function, not the routine’s definition.)

SET UDFPARMS lets you change the default, and muck up your system worse than you ever anticipated. If you SET UDFPARMS to REFERENCE, all parameters are passed to functions by reference. Don’t do that!

You can always pass a parameter to a function by reference by putting an “@” in front of it in the function call. This is a local, readable solution to the problem. Changing UDFPARMS can have all kinds of unforeseen effects on your code and on other people’s code that you use.

Not surprisingly, SET(“UDFPARMS”) returns either “VALUE” or “REFERENCE”. If you feel you must change the setting of UDFPARMS, be sure to save and restore the old setting.

See Also

Function, Local, Parameters(), PCount(), Private, Procedure, Set