xHarbour Reference Documentation > Statement Reference |
Declares a function along with its formal parameters.
[STATIC] [UTILITY] FUNCTION <funcName>( [<params,...>] ) [FIELD <fieldName,...> [IN <aliasName>]] [MEMVAR <var_Dynamic,...>] [LOCAL <var_Local> [:= <expression>] ,... ] [STATIC <var_Static> [:= <expression>] ,... ] <Statements> RETURN <retVal>
Optionally, the names of parameters <params,...> accepted by the function can be specified as a comma separated list. These function parameters have LOCAL scope within the function.
When the function is declared as STATIC FUNCTION, it is only visible within the PRG file that contains the function declaration and cannot be invoked from elsewhere.
The FUNCTION statement declares a function along with an optional list of parameters accepted by the function. Statements programmed in the function body form a self-contained part of a program that is executed when a function is called. Thus, tasks of a program can be split into several functions, each of which performs a sub-task when invoked.
The body of a function ends with the next FUNCTION, PROCEDURE or CLASS declaration, or at the end of file, which implies that function declarations cannot be nested.
The execution of a function ends when a RETURN statement is encountered in the function body, which must return a value <retVal> to the calling routine. This value is mandatory for functions and can be of any data type. The RETURN value is the only difference between functions and procedures.
When a function is declared with the STATIC modifier, its visibility is restricted to the PRG file that contains the STATIC FUNCTION declaration. The names of STATIC functions are resolved by the compiler and do not exist at runtime of a program. The names of non-STATIC functions, also referred to as public functions, are resolved by the linker and do exist at runtime. Thus, public functions can be accessed by the Macro operator (&) while STATIC functions cannot.
It is possible to declare STATIC functions with the same symbolic name in different PRG files. A name conflict to a public function with the same name declared in another PRG file does not arise. However, the symbolic names of public functions, procedures or classes must always be unique.
When a function is invoked with values being passed to it, they are assigned to the formal parameters declared with <params,...>. All variables declared in this list are LOCAL variables and their visibility is restricted to the statements programmed in the function body.
The number of values passed to a function does not need to match the number of parameters declared. When fewer values are passed, the corresponding parameters are initialized with NIL. When more values are passed, the additional values are not asssigned to parameters but can be retrieved using function HB_AParams().
Undefined parameter list a function can be declared with an undefined parameter list using the ellipsis sign (...) as a placeholder for the parameter list. A function declared in such way can receive an unknown number of parameters.
See also: | FIELD, HB_AParams(), LOCAL, MEMVAR, METHOD (declaration), PARAMETERS, PCount(), PRIVATE, PROCEDURE, PUBLIC, RETURN, STATIC |
Category: | Declaration , Statements |
// The example shows two functions used to calculate the number of // days for a month. PROCEDURE Main ? DaysOfMonth( StoD( "20000201" ) ) // Result: 29 ? DaysOfMonth( StoD( "20010201" ) ) // Result: 28 ? DaysOfMonth( StoD( "20040201" ) ) // Result: 29 ? DaysOfMonth( StoD( "20050301" ) ) // Result: 31 ? DaysOfMonth( StoD( "20051101" ) ) // Result: 30 RETURN FUNCTION DaysOfMonth( dDate ) LOCAL nMonth IF Valtype( dDate ) <> "D" dDate := Date() ENDIF nMonth := Month( dDate ) IF nMonth == 2 RETURN IIf( IsLeapYear( dDate ), 29, 28 ) ELSEIF nMonth $ {4,6,9,11} RETURN 30 ENDIF RETURN 31 STATIC FUNCTION IsLeapYear( dDate ) LOCAL nYear := Year( dDate ) RETURN ( nYear % 4 == 0 ) .OR. ( nYear % 400 == 0 )
// The example demonstrates how an unknown number of command line // arguments passed to an xHarbour application can be processed. PROCEDURE Main( ... ) LOCAL aArg := HB_AParams() LOCAL cArg FOR EACH cArg IN aArg DO CASE CASE Upper( cArg ) IN ("-H/H-?/?") ? "Help requested" CASE .NOT. cArg[1] IN ( "-/" ) ?? " argument:", cArg CASE Upper( cArg ) IN ("-X/X") ? "Execution requested" OTHERWISE ? "Unknown:", cArg ENDCASE NEXT RETURN
http://www.xHarbour.com