INLINE METHOD
Declares and implements an inline method that spans across multiple lines.
Syntax
INLINE METHOD <MethodName>( [<params,...>] )
<.. program code ..>
ENDMETHOD
Arguments
<MethodName>
This is the symbolic name of the method to implement. It must begin with a letter or underscore followed by digits, letters or underscores. The symbolic name can contain up to 63 characters.
<params,...>
This is a acomma separated list of formal parameters accepted by the method.
ENDMETHOD
This ends the implementation of an INLINE METHOD that spans across multiple lines.
Description
Methods are declared within theclass declaration. When a method is also implemented between CLASS and ENDCLASS, it is called an INLINE method. The INLINE METHOD declaration declares an inline method whose implementation spans across multiple lines. The end of this implementation must be indicated with the ENDMETHOD statement.
INLINE METHOD exists for compatibility reasons. It is recommended to declare a method with METHOD (declaration)and implement it separately withMETHOD (implementation).
Note: if a method can be implemeted with one line of code, the INLINE option of theMETHOD (declaration)can be used.
Info
See also: CLASS,METHOD (declaration),METHOD (implementation) Category: Class declaration,Declaration,xHarbour extensions
Header: hbclass.ch Source: vm\classes.c
LIB: xhb.lib
DLL: xhbdll.dll
Example
// The example implements a class whose methods are entirely implemented // INLINE. Objects of the class extract subsequent lines of an ASCII text // until no more text lines are available.
#include "hbclass.ch"
PROCEDURE Main
LOCAL obj := LineParser():new( Memoread( "Test.prg" ) )
INLINE METHOD
? obj:line obj:nextLine() ENDDO
RETURN
CLASS LineParser PROTECTED:
DATA text
INLINE METHOD extract
LOCAL i := At( Chr(13)+Chr(10), ::text ) IF i == 0
::line := ::text ::text := ""
ELSE
::line := SubStr( ::text, 1, i-1 ) ::text := SubStr( ::text, i+2 ) ENDIF
RETURN self ENDMETHOD
EXPORTED:
DATA line INIT "" READONLY
METHOD init( cText ) INLINE ( ::text := cText, ::extract(), self ) METHOD eof INLINE ( Len( ::text + ::line ) == 0 )
INLINE METHOD nextLine ::extract()
RETURN ::line ENDMETHOD
ENDCLASS
LOCAL
LOCAL
Declares and optionally initializes a local memory variable.
Syntax
LOCAL <varName> [:= <xValue> ]
Arguments
LOCAL <varName>
<varName> is the symbolic name of the local variable to declare.
<xValue>
<xValue> is an optional value to assign to the LOCAL variable after being declared. To assign a value, the inline assignment operator (:=) must be used. The simple assignment operator (=) cannot be used.
Description
The LOCAL statement declares a lexical memory variable that has LOCAL scope. Local variables are resolved by the compiler, i.e. their symbolic name cannot be retrieved during runtime. This makes access to LOCAL variables much faster than to dynamic memory variables of PRIVATE or PUBLIC scope, whose symbolic variable names exist at runtime.
The names of LOCAL variables cannot be included in macro-expressions since they cannot be resolved by the macro operator (&). This operator requires the symbolic name of a variable to exist at runtime.
The visibility and lifetime of LOCAL variables is restricted to the function, procedure or method that declares a LOCAL variable. Unlike PRIVATE or PUBLIC variables, LOCAL variables cannot be seen in a subroutine. To make the value of a LOCAL variable visible in a subroutine, it must be passed as a parameter to the subroutine.
When a routine executes the RETURN statement, all LOCAL variables declared in that routine are discarded and their values become subject to garbage collection.
The lines in PRG source code preceding the LOCAL statement may not call executable code. They can only contain declaration statements, i.e. only the FUNCTION, METHOD, PROCEDURE statements, and the FIELD, MEMVAR, PARAMETERS, PRIVATE, PUBLIC, STATIC variable declarations are allowed to precede the LOCAL statement.
It is possible to initialize a local variable already in the LOCAL statement. To accomplish this, the inline-assignment operator must be used. The value of any valid expression can be assigned. This includes literal values and the return values of functions.
Note: If a PRIVATE or PUBLIC variable exists that has the same symbolic name as a LOCAL variable, only the LOCAL variable is visible. PRIVATE or PUBLIC variables with the same name become visible again, when the LOCAL variable gets out of scope, i.e. when the routine that declareS the LOCAL variable returns or calls a subroutine.
LOCAL
Info
See also: FUNCTION,GLOBAL,PARAMETERS,PRIVATE,PROCEDURE,PUBLIC,STATIC Category: Declaration,Statements
Example
// The example demonstrates the visibility of LOCAL and PRIVATE // memory variables
PROCEDURE Main
PRIVATE myVar := "Private Var"
? Procname(), myVar Test1()
RETURN
PROCEDURE Test1
LOCAL myVar := "Local Var"
// PRIVATE myVar is unvisible
? Procname(), myVar Test2()
RETURN
PROCEDURE Test2
// PRIVATE myVar is visible
? Procname(), myVar RETURN
MEMVAR
MEMVAR
Declares PRIVATE or PUBLIC variables.
Syntax
MEMVAR <varName,...>
Arguments
MEMVAR <varName,...>
This is a comma separated list of symbolic names identifying field variables.
Description
The MEMVAR statement declares symbolic names of dynamic memory variables of PRIVATE or PUBLIC scope. This instructs the compiler to resolve unaliased variable names to memory variables, not field. All variables listed in <varName,...> that appear in program code without alias name and alias operator, are treated as if they are listed with the M-> alias name.
The scope of the MEMVAR statement depends on the place of declaration:
1. When the MEMVAR declaration appears at the top of a PRG file before any other executable statement, the declaration has file wide scope, i.e. it is valid throughout the entire PRG file.
2. When the MEMVAR declaration follows a FUNCTION, METHOD or PROCEDURE declaration, the variable is treated as memory variable only in the routine that declares the MEMVAR.
The lines in PRG source code preceding the MEMVAR declaration may not call executable code. They can only contain declaration statements, i.e. only the FUNCTION, METHOD, PROCEDURE
statements, and the FIELD, LOCAL, PARAMETERS, or STATIC variable declarations are allowed to precede the MEMVAR statement.
Info
See also: FIELD,GLOBAL,LOCAL,PRIVATE,PUBLIC,STATIC Category: Declaration,Statements
Example
// The example demonstrates the difference of a declared and // undeclared memory variable of PRIVATE scope.
MEMVAR myVar PROCEDURE Main
x := "myVar" // compiler warning myVar := "Hello World" // no compiler warning
? x
? &x RETURN
MESSAGE
MESSAGE
Declares a message name for a method.
Syntax
MESSAGE <MessageName> METHOD <MethodName>
MESSAGE <MessageName> IN <SuperClass>
MESSAGE <MessageName> IS <MethodName> IN <SuperClass>
Arguments
<MessageName>
This is the symbolic name of a message to declare for a class.
METHOD <MethodName>
This is the symbolic name of the method to execute when an object receives <MessageName>
as a message.
IN <SuperClass>
Optionally, the name of the super class can be specified to which the message should be sent.
This requires the class to inherit one or more other classes.
IS <MethodName>
When a message should be directed to a super class, the method to invoke in the super class can be specified with <MethodName>.
Description
The MESSAGE statement can only be used within the class declarationbetween CLASS and
ENDCLASS. It declares a message that invokes a method of a different name in the declared class or its super class.
MESSAGE is used to resolve ambiguities when a class inherits from one or more super classes which have the same method names. The statement can also be used to invoke a method via an alternative name.
Info
See also: ACCESS,ASSIGN,CLASS,DATA,DELEGATE,METHOD (declaration) Category: Class declaration,Declaration,xHarbour extensions
Header: hbclass.ch Source: vm\classes.c
LIB: xhb.lib
DLL: xhbdll.dll
Example
// In the example a Subclass uses the method implementation // of a Super class but redefines the message to send to // an object. Message :print() invokes method :show().
#include "Hbclass.ch"
PROCEDURE Main
MESSAGE LOCAL obj := TextFile():new( "Text.prg" )
obj:open() obj:print() obj:close() RETURN
CLASS Text EXPORTED:
DATA string
METHOD init(c) INLINE ( ::string := c, self ) METHOD show INLINE QOut( ::string )
ENDCLASS
CLASS TextFile FROM Text EXPORTED:
DATA fileName METHOD init METHOD open METHOD close
MESSAGE print IS show IN Text ENDCLASS
METHOD init( cFile, cText ) CLASS TextFile ::fileName := cFile
IF Valtype( cText ) == "C"
::text:init( cText ) ELSE
::text:init( Memoread(::fileName ) ) ENDIF
RETURN self
METHOD open CLASS TextFile SET ALTERNATE ON
SET ALTERNATE TO (::fileName) RETURN
METHOD close CLASS TextFile SET ALTERNATE TO
SET ALTERNATE OFF RETURN
METHOD (declaration)
METHOD (declaration)
Declares the symbolic name of a method.
Syntax
METHOD <MethodName>[(<params,...>] )] [INLINE <expression>] [SYNC]
Arguments
<MethodName>
This is the symbolic name of a single method to declare. It must begin with a letter or underscore followed by digits, letters or underscores. A symbolic name can contain up to 63 characters.
(<params,...>)
A declaration of formal parameters enclosed in parentheses is required when the method is declared as INLINE. If INLINE is not used, the method can be declared without parameters.
INLINE <expression>
This is the expression which is executed when an INLINE method is invoked. <expression>
must be one line of code. The code cannot contain commands but only function and method calls.
SYNC
The SYNC option declares a "synchronized" method. This is only required in multi-threaded applications when a method must be protected against simultaneous access by multiple-threads.
Methods declared with the SYNC attribute can be executed only by one thread at a time. Refer to functionStartThread()for more information on multiple threads.
Description
When the METHOD statement occurs in theclass declarationbetween CLASS and ENDCLASS, it declares the symbolic name of a method. This name must be sent to an object to invoke the method.
The program code for a declared method must be implemented with a separateMETHODdeclaration that follows the ENDCLASS statement. If, however, the method code can be programmed in one line, method declaration and implementation can be coded within the class declaration using the INLINE option. INLINE methods are not implemented separately from the class declaration.
When a method is invoked, the object executing the method is accessible in the code with the reserved variable name self. This can be abbreviated with two colons (::).