PUBLIC

PUBLIC

Create and initialize public memory variables and arrays

Syntax

       PUBLIC <identifier> [[:= <initializer>], ... ]

Arguments

<identifier> is the name of a public variable or array to create. If the <identifier> is followed by square brackets ([ ]), it is created as an array. If the <identifier> is an array, the syntax for specifying the number of elements for each dimension can be array[<nElements>, <nElements2>, …] or array[<nElements>][<nElements2>]…. The maximum number of elements per dimension is 4096. The maximum number of dimensions per array is limited only by available memory.

<initializer> is the optional assignment of a value to a new public variable. Array identifiers, however, cannot be given values with an <initializer>. An <initializer> for a public variable consists of the inline assignment operator (:=) followed by any valid Harbour expression including a literal array. Except for arrays, if no <initializer> is specified, public variables are initialized to false (.F.). This is an exception to the general rule that uninitialized variables are NIL. With arrays, however, the initial value of each element is NIL.

A list of variables and arrays can be created and, optionally, initialized with one PUBLIC statement if each definition is separated by a comma.

Description

The PUBLIC statement creates variables and arrays visible to all procedures and user-defined functions in a program. Public variables exist for the duration of the program or until explicitly released with CLEAR ALL, CLEAR MEMORY, or RELEASE. Declaring private, local, or static variables or arrays with the same name as existing public variables temporarily hides those public variables until the overriding variables are released or are no longer visible. An attempt to create a public variable with the same name as an existing and visible private variable is simply ignored (see Notes below for an exception).

Attempting to specify a PUBLIC variable that conflicts with a previous FIELD, LOCAL, or STATIC declaration of the same name results in a fatal compiler error. This is true regardless of the scope of the declaration.

PUBLIC statements are executable statements and, therefore, must be specified within the body of a procedure or user-defined function definition. They also must follow all compile-time declarations, such as FIELD, LOCAL, MEMVAR, and STATIC.

The maximum number of public and private variables and arrays that can simultaneously exist in a single program is 2048.

For more information on variable declarations and scoping, refer to the Variables section in the “Basic Concepts” chapter.

Notes

. Public array name conflicts with existing private variables: The statement, PUBLIC x[10], will not create the public array x if there is already a private or public variable x. It will, however, destroy the contents of the existing x, replacing it with a reference to a ten-element array.

Examples

       .  This example creates two PUBLIC arrays and one PUBLIC
          variable:
          PUBLIC aArray1[10, 10], var2
          PUBLIC aArray2[20][10]
       .  The following PUBLIC statements create variables and
          initialize them with values:
          PUBLIC cString := SPACE(10), cColor := SETCOLOR()
          PUBLIC aArray := {1, 2, 3}, aArray2 := ARRAY(12, 24)

Seealso

LOCAL, MEMVAR, PARAMETERS, PRIVATE, STATIC

PROCEDURE

PROCEDURE

Declare a procedure name and formal parameters

Syntax

       [STATIC] PROCEDURE <idProcedure> [(<idParam list>)]
              [FIELD <idField list> [IN <idAlias>]
              [LOCAL <identifier> [[:= <initializer>], ... ]]
              [MEMVAR <identifier list>]
              [STATIC <identifier> [[:= <initializer>], ... ]]
              .
              . <executable statements>
              .
              [RETURN]

Arguments

<idProcedure> is the name of the procedure to be declared. Procedure names can be any length, but only the first 10 characters are significant. Names can contain any combination of characters, numbers, or underscores, but leading underscores are reserved.

<idParam list> is the declaration of one or more parameter variables. Variables specified in this list are declared local.

STATIC PROCEDURE declares a procedure that can be called only by procedures and user-defined functions declared in the same program (.prg) file.

FIELD declares a list of identifiers, <idField list>, to use as field names whenever encountered. If the IN clause is specified, referring to the declared name, <idAlias> is a reference to the appropriate work area of the specified database.

LOCAL declares and optionally initializes a list of variables or arrays whose visibility and lifetime is the current procedure.

<identifier>, <identifier list> is a label or labels used as variable or array names. If the <identifier> is followed by square brackets ([ ]), it is created as an array. If the <identifier> is an array, the syntax for specifying the number of elements for each dimension can be array[<nElements>, <nElements2>, …] or array[<nElements>][<nElements2>]… The maximum number of elements per dimension is 4096. The maximum number of dimensions per array is limited only by available memory.

<initializer> is the value to which an optional inline assignment sets the <identifier> variable–essentially, the assignment operator, (:=) –followed by any valid Harbour expression, including a literal array. If no <initializer> is specified, variables are initialized to NIL. In the case of arrays, all element are initialized to NIL.

MEMVAR declares a list of identifiers, <identifier list>, to use as private or public memory variables or arrays whenever encountered.

STATIC declares and, optionally, initializes a list of variables or arrays whose visibility is the current procedure and whose lifetime is the duration of the program.

RETURN passes control back to the calling procedure or user-defined function. If a RETURN is not specified, control passes back to the calling routine when the procedure definitions ends. In all cases, the compiler terminates the procedure definition when it encounters another PROCEDURE statement, FUNCTION statement, or end of file character.

Description

The PROCEDURE statement declares a procedure and an optional list of local variables to receive parameters passed from a calling routine. A procedure is a subprogram comprised of a set of declarations and statements executed whenever you refer to <idProcedure>, followed by an open and close parentheses pair or with the DO statement. A procedure definition begins with a PROCEDURE statement and ends with the next PROCEDURE statement, FUNCTION statement, or end of file.

Procedures that encapsulate computational blocks of code provide readability and modularity, isolate change, and help manage complexity.

A procedure in Harbour is the same as a user-defined function, with the exception that it always returns NIL. Each procedure must begin with a PROCEDURE statement and may, optionally, contain a RETURN statement to return control to the calling procedure or user-defined function. A RETURN statement, however, is not required. Procedure declarations cannot be nested within other procedure definitions.

The visibility of procedure names falls into two classes. Procedures that are visible anywhere in a program are referred to as public procedures and declared with a PROCEDURE statement. Procedures that are visible only within the current program (.prg) file are referred to as static procedures and declared with a STATIC PROCEDURE statement. Static procedures have filewide scope.

Static procedures are quite useful for a number of reasons. First, they limit visibility of a procedure name thereby restricting access to the procedure. Because of this, subsystems defined within a single program (.prg) file can provide an access protocol with a series of public procedures and conceal the implementation details of the subsystem within static procedures and functions. Second, since the static procedure references are resolved at compile time, they preempt references to public procedures and functions which are resolved at link time. This ensures that, within a program file, a reference to a static procedure executes that procedure if there is a name conflict with a public procedure or function.

For more information on procedures, variable declarations, and parameter passing, refer to the “Basic Concepts” chapter.

Notes

. Calling a procedure: There are two ways to call a procedure in Harbour. The first and preferred way is the function-calling convention. Here you call the procedure as you would a Harbour function on a line by itself:

<idProcedure>([<argument list>])

The second and obsolete way is the command-calling convention using the DO…WITH command. The two methods of calling procedures differ only in the default method of passing parameters. The function- calling convention passes variables by value as a default, whereas the command-calling convention passes them by reference as a default.

A procedure can also be called as an aliased expression if it is prefaced with an alias and invoked using the function-calling convention, like this: <idAlias> ->(<idProcedure>(<argument list>)) When called as an aliased expression, the work area associated with <idAlias> is selected, the procedure is executed, and then the original work area is reselected. Like an expression or function, an aliased procedure can be specified on a line by itself. A procedure in Harbour may call itself recursively. This means you can call a procedure in the same procedure definition.

. Parameters: Procedures like user-defined functions can receive parameters passed from a calling procedure, user-defined function, or the DOS command line. A parameter is a place for a value or reference. In Harbour there are two ways to receive parameters: a list of local variable names can be declared as a part of the PROCEDURE declaration (referred to as formal parameters), or a list of private variables can be specified in a separate PARAMETERS statement. Note that you cannot mix a declaration of formal parameters with a PARAMETERS statement. Attempting this will cause a fatal compiler error.

Procedures receive parameters in the order passed. In Harbour the number of parameters need not match the number of arguments passed. Arguments can be skipped or left off the end of the argument list. A parameter not receiving a value or reference is initialized to NIL. If arguments are specified, PCOUNT() returns the position of the last argument passed.

Parameters specified in a procedure can receive arguments passed by value or by reference. The default method for expressions and variables depends on the calling convention. With the function-calling convention, the default passing method for expressions and variables is by value. This includes variables containing references to arrays and objects. With the command- calling convention, the default method for passing variables is by reference except for field variables, which are always passed by value. Whenever a field variable is passed, it must be specified enclosed in parentheses unless declared with the FIELD statement. Failure to do so will generate a runtime error.

Examples

       .  This example shows a skeleton of a typical Harbour
          procedure that uses lexical variables:
          PROCEDURE Skeleton( cName, cClassRoom, nBones, ;
                                  nJoints )
             LOCAL nCrossBones, aOnHand := {"skull", ;
                                           "metacarpals"}
             STATIC nCounter := 0
             .
             . <executable statements>
             .
             RETURN
       .  This example determines whether an argument was skipped by
          comparing the parameter to NIL:
          PROCEDURE MyProc( param1, param2, param3 )
             IF param2 != NIL
                param2 := "default value"
             ENDIF
             .
             . <statements>
             .
             RETURN
       .  This example invokes the procedure, UpdateAmount(), as an
          aliased expression:
          USE Invoices NEW
          USE Customer NEW
          Invoices->(UpdateAmount(Amount + Amount * nInterest))

Seealso

FUNCTION, LOCAL, PARAMETERS, PCOUNT(), RETURN, STATIC

PRIVATE

Create and initialize private memory variables and arrays

Syntax

       PRIVATE <identifier> [[:= <initializer>], ... ]

Arguments

<identifier> is the name of a private variable or array to create. If the <identifier> is followed by square brackets ([ ]), an array is created and assigned to the <identifier>. When the <identifier> specification indicates an array, the syntax for specifying the number of elements for each dimension can be array[<nElements>, <nElements2>, …] or array[<nElements>][<nElements2>]… The maximum number of elements per dimension is 4096. The maximum number of dimensions is limited only by available memory.

<initializer> is the optional assignment of a value to a new private variable. An array cannot be given values with an <initializer>. An <initializer> for a private variable consists of the inline assignment operator (:=) followed by any valid Harbour expression including a literal array. If no explicit <initializer> is specified, the variable is initialized to NIL. In the case of an array, each element is initialized to NIL.

You can create and, optionally, initialize a list of variables and arrays with one PRIVATE statement if the definitions are separated by commas.

Description

The PRIVATE statement creates variables and arrays visible within the current and invoked procedures or user-defined functions. This class of variable is said to have dynamic scope. Private variables exist for the duration of the active procedure or until explicitly released with CLEAR ALL, CLEAR MEMORY, or RELEASE. When a private variable or array is created, existing and visible private and public variables of the same name are hidden until the current procedure or user-defined function terminates.

Attempting to specify a PRIVATE variable that conflicts with a previous FIELD, LOCAL, or STATIC declaration of the same name results in a fatal compiler error. This is true regardless of the scope of the declaration.

PRIVATE statements are executable statements and, therefore, must be specified within the body of a procedure or user-defined function and must follow all variable declarations, such as FIELD, LOCAL, MEMVAR, and STATIC.

In addition to the PRIVATE statement, private variables are also created in two other ways:

. Assignment to a variable that does not exist or is not visible will create a private variable .

Parameters received using the PARAMETERS statement are created as private variables with the same lifetime and visibility.

No more than 2048 private and public variables and arrays can simultaneously exist in a single program.

For more information on variable declarations and scoping, refer to the Variables section in the “Basic Concepts” chapter.

Notes

. Compatibility: The ALL, LIKE, and EXCEPT clauses of the PRIVATE statement supported by other dBASE dialects are not supported.

Examples

       .  This example creates two PRIVATE arrays and three other
          PRIVATE variables:
          PRIVATE aArray1[10], aArray2[20], var1, var2, var3
       .  This example creates a multidimensional private array using
          each element addressing convention:
          PRIVATE aArray[10][10][10], aArray2[10, 10, 10]
       .  This example uses PRIVATE statements to create and initialize
          arrays and variables:
          PRIVATE aArray := { 1, 2, 3, 4 }, ;
                aArray2 := ARRAY(12, 24)
          PRIVATE cChar := SPACE(10), cColor := SETCOLOR()

Seealso

FIELD, LOCAL, MEMVAR, PARAMETERS, PUBLIC, STATIC

PARAMETERS

PARAMETERS

Declares private parameter variables

Syntax

PARAMETERS <idPrivate list>

Arguments

<idPrivate list> is one or more parameter variables separated by commas.

The number of receiving variables does not have to match the number of arguments passed by the calling procedure or user-defined function.

Description

The PARAMETERS statement declares private variables to receive passed values or references. Receiving variables are referred to as parameters. The values or references actually passed by a procedure or user-defined function invocation are referred to as arguments.

When a PARAMETERS statement executes, all variables in the parameter list are created as private variables and all public or private variables with the same names are hidden until the current procedure or user-defined function terminates. A PARAMETERS statement is an executable statement and, therefore, can occur anywhere in a procedure or user-defined function, but must follow all compile-time variable declarations, such as FIELD, LOCAL, MEMVAR, and STATIC.

Parameters can also be declared as local variables if specified as a part of the PROCEDURE or FUNCTION declaration statement (see the example). Parameters specified in this way are referred to as formal parameters. Note that you cannot specify both formal parameters and a PARAMETERS statement with a procedure or user-defined function definition. Attempting to do this results in a fatal compiler error and an object file is not generated.

In Harbour the number of arguments and parameters do not have to match. If you specify more arguments than parameters, the extra arguments are ignored. If you specify fewer arguments than parameters, the extra parameters are created with a NIL value. If you skip an argument, the corresponding parameter is initialized to NIL. The PCOUNT() function returns the position of the last argument passed in the list of arguments. This is different from the number of parameters passed since it includes skipped parameters.

Examples

     .  This user-defined function receives values passed into private
        parameters with a PARAMETERS statement:

        FUNCTION MyFunc
           PARAMETERS cOne, cTwo, cThree
           ? cOne, cTwo, cThree
           RETURN NIL

     .  This example is similar, but receives values passed into local
        variables by declaring the parameter variables within the FUNCTION
        declaration:

        FUNCTION MyFunc( cOne, cTwo, cThree )
           ? cOne, cTwo, cThree
           RETURN NIL

See Also

 FUNCTION, LOCAL, PCOUNT(), PRIVATE, PROCEDURE, STATIC

MEMVAR

MEMVAR

Declares private and public variables and arrays.

Syntax

      MEMVAR <xVar>

Arguments

<xVar> Memory variable Name

Description

This command tells the compiler to resolve any reference to a memory variable designated within this list s if it possessed an explicit memory variable alias with either the M-> or MEMVAR-> prefix.Only those memory variables that do not contain any such explicit are affected by this command. Those memory variabls within macro expansions are not affected by this command.

The MEMVAR declaration must apear before any executable commands;it is similat to the LOCAL, STATIC, FIELD, PARAMETERS, FUNCTION, and PROCEDURE commands statements.

Examples

      MEMVAR y AS NUMERIC
      PROCEDURE Main()
         LOCAL n, lVar

         n := iif( lVar, "A", 3 )
         n := 2
         n := "a"
         n := seconds() + 2
         n := int( seconds() + 2 )
         y := n
         ? y
         RETURN

Tests

      See tests/testwarn.prg for more examples

Compliance

Clipper

Platforms

All

Files

None.

Seealso

LOCAL, STATIC, FIELD, PRIVATE, PUBLIC

LOCAL

LOCAL

Initializes a local memory variable or array

Syntax

      LOCAL <xVar> [:= <xInit> ]

Arguments

<xVar> Name of a memory variable or array.

<xInit> Value to be assinged to a variable or array

Description

This command created a LOCAL memory variable or array. The name of either is specified in <xVar>. If more then one variable is being initialized with the LOCAL command, separate each entry with a comma. If a variable or an array is to be assingned a start-up value, that expression may be specified in <xInit> and folling. Is Strong type compile mode is used, the Compiler will check if the value recived matchs the type specified in <xType>.

LOCAL varibles are symbols generated at run time and are resolved at compile time. The visibility and life span of a LOCAL variable or array is limited to the function or procedure in which it is defined.

No macro expansions are allowed in the LOCAL declaration statement.

No Harbour command other then FUNCTION, PROCEDURE, PUBLIC, PRIVATE, PARAMETERS, MEMVAR, STATIC and FIELD, may precede the LOCAL command.

LOCAL array reference may not be initialized (i.e., assigned values) on the same command line as the LOCAL command statement. This can be done later in the program.

LOCAL variables and arrays are not affected by the RELEASE command.

Examples

      PROCEDURE Main()
         LOCAL n, lVar

         n := iif( lVar, "A", 3 )
         n := 2
         n := "a"
         n := seconds() + 2
         n := int( seconds() + 2 )
         RETURN

Tests

      See tests/testwarn.prg for more examples

Compliance

Clipper

Platforms

All

Files

None

Seealso

FIELD, PRIVATE, PUBLIC, STATIC, MEMVAR

FIELD

FIELD

Declares a list of database field names.

Syntax

      FIELD <xField> [,<xFieldn...>  [in <cDatabase>]

Arguments

<xField> A valid field name

<xFieldn> Additional field name

<cDatabase> An valid alias name

Description

This command declares the names of fields <xField> (and <xFieldn> and following) with an optional alias identifier as <cDatabase> for each. This command allow Harbour to resolve any reference to a field specified in the field list by viewing it as a field when it is not referenced by an alias. If a field is not listed in this list and it is not explicity tagged with an alias indentifier, it may be viewed as a memory variable, which may cause run-time errors. This command has no effect on memory variables or on field reference buried within a macro expression.

Examples

      PROCEDURE Main()
         FIELD Id
         FIELD Name
         USE tests NEW
         Name := "Sales"
         Id := 5
         USE
         RETURN

Tests

      See tests/testwarn.prg

Compliance

Clipper

Platforms

All

Files

None.

Seealso

MEMVAR, PRIVATE, PUBLIC, STATIC