• No results found

EXTEND CLASS...WITH METHOD

In document xHarbour Language Reference Guide (Page 127-134)

EXTEND CLASS...WITH METHOD

Adds a new method to an existing class.

Syntax

EXTEND CLASS <ClassName> WITH ;

[ MESSAGE <MessageName>] METHOD <FunctionName>

or

EXTEND CLASS <ClassName> WITH ;

MESSAGE <MessageName> INLINE <expression>

Arguments

<ClassName>

This is the symbolic name of an existing class to add a new method to.

MESSAGE <MessageName>

This is the symbolic name of the message which invokes the new method.

METHOD <FunctionName>

This is the symbolic name of the function implementing the code for the new method. If

<MessageName> is omitted, <FunctionName> defines also the message that must be sent to an object for invoking the method.

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.

Description

The EXTEND CLASS...WITH METHOD statement allows for adding new methods to a declared class outside the class declaration. This way, a class can be enhanced even if the source code of the class is not available. The EXTEND CLASS statemend can modify all classes existing in xHarbour.

The new method is either implemented as aSTATIC FUNCTIONor as an INLINE expression. The self object is retrieved in both cases with functionHB_QSelf().

Note: an alternative for enhancing an existing class is to use the FROM option of theCLASSstatement and create a sub-class of an existing class.

EXTEND CLASS...WITH METHOD

Info

See also: ASSOCIATE CLASS,CLASS,EXTEND CLASS...WITH DATA,HB_QSelf(), METHOD...OPERATOR,OPERATOR,OVERRIDE METHOD

Category: Class declaration,Declaration,xHarbour extensions Header: hbclass.ch

Source: vm\classes.c

LIB: xhb.lib

DLL: xhbdll.dll

Example

// The example adds a method to the "root" class of xHarbour: HBObject().

// All new classes inherit from this class. This is used in the example // for tracing variables depending on their data types in different log // files.

#include "HbClass.ch"

PROCEDURE Main

LOCAL obj, nValue := 2, dDate := Date()

EXTEND CLASS HBObject WITH MESSAGE log METHOD LogData ENABLE TYPE CLASS ALL

obj := Test():new( "xHarbour" ) obj:log( "Objects.log" )

nValue:log( "Numerics.log" ) dDate:log( "Dates.log" ) RETURN

CLASS Test EXPORTED:

DATA value

METHOD init(x) INLINE (::value := x, self) ENDCLASS

STATIC FUNCTION LogData( cLogFile ) LOCAL self := HB_QSelf()

LOCAL cOldFile

IF .NOT. Set( _SET_TRACE ) RETURN self

ENDIF

IF Valtype( cLogFile ) == "C"

cOldFile := Set( _SET_TRACEFILE, cLogFile ) ENDIF

Tracelog( self ) IF cOldFile <> NIL

Set( _SET_TRACEFILE, cOldFile ) ENDIF

RETURN self

EXTERNAL

EXTERNAL

Declares the symbolic name of an external function or procedure for the linker.

Syntax

EXTERNAL <name1> [,<nameN>]

Arguments

EXTERNAL <name>

This is the symbolic name of a function or procedure to declare for the linker. When multiple names are declared, they must be separated with commas.

Description

The EXTERNAL statement declares a symbolic name of a function or procedure for the linker. This is usually required when there is no direct call of a function or procedure in PRG code, for example when a function is only called within a macro-expression using the macro-operator. By declaring the

symbolic name of a function as EXTERNAL, the linker is forced to link the corresponding function to the executable file.

Note: It is common practice to use the EXTERNAL declaration within an #include file. This way it is assured that functions are available in all PRG files that may call them indirectly.

Info

See also: #include,ANNOUNCE,REQUEST Category: Declaration,Statements

Example

// The example forces the linker to link three functions that are only // called within a macro expression.

EXTERNAL Memoedit, Memoread, Memowrit MEMVAR fileName

STATIC cEditor := "Memowrit(fileName,Memoedit(Memoread(fileName)))"

PROCEDURE Main( cFile ) fileName := cFile

&cEditor RETURN

FIELD

FIELD

Declares a field variable

Syntax

FIELD <fieldName,...> [IN <aliasName>]

Arguments

FIELD <fieldNames,...>

This is a comma separated list of symbolic names identifying field variables.

IN <aliasName>

Optionally, the alias name of the work area that holds field variables can be specified.

Description

The FIELD statement declares symbolic names of variables whose values are stored in database files.

This instructs the compiler to resolve unaliased variable names to field variables, not memory

variables. All variables listed in <fieldNames,...> that appear in program code without alias name and alias operator, are treated as if they are listed with the FIELD-> alias name, or the one specified with the IN clause.

The FIELD statement does not verify if the field variables exist at runtime or if a database is open with

<aliasName> as name. When the declared field variable does not exist at runtime, an error is generated.

The scope of the FIELD variable depends on the place of declaration:

1. When the FIELD 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 FIELD declaration follows a FUNCTION, METHOD or PROCEDURE declaration, the variable is treated as FIELD variable only in the routine that declares the FIELD.

The lines in PRG source code preceding the FIELD declaration may not call executable code. They can only contain declaration statements, i.e. only the FUNCTION, METHOD, PROCEDURE statements, and the LOCAL, MEMVAR, PARAMETERS, or STATIC variable declarations are allowed to precede the FIELD statement.

Info

See also: FUNCTION,GLOBAL,LOCAL,MEMVAR,PROCEDURE,STATIC Category: Declaration,Statements

Example

PROCEDURE Main

FIELD InvoiceNo, AmountDue, Payment IN Inv FIELD CustNo , FirstName, LastName IN Cust USE Customer ALIAS Cust SHARED

INDEX ON CustNo TO CustA

USE Invoice ALIAS Inv SHARED NEW SET RELATION TO CustNo INTO Cust

FIELD GO TOP

SET ALTERNATE TO NotPaid.txt SET ALTERNATE ON

DO WHILE .NOT. Eof() IF Payment == 0

? CustNo, Lastname, FirstName, InvoiceNo, AmountDue ENDIF

SKIP ENDDO

SET ALTERNATE TO DbCloseAll() RETURN

FOR

FOR

Executes a block of statements a specific number of times.

Syntax

FOR <nCounter> := <nStart> TO <nEnd> [STEP <nIncrement>]

<Statements>

FOR <nCounter> := <nStart>

<nCounter> is the name of the variable that holds a counter value used to control the number of iterations of the FOR...NEXT loop. If <nCounter> does not exist when the loop is entered, it is created as a PRIVATE variable. The value <nStart> is a numeric start value to initialize

<nCounter> with when the FOR statement is executed for the first time.

TO <nEnd>

<nEnd> is a numeric value that controls the termination of the FOR...NEXT loop. As soon as

<nCounter> is greater than or equal to <nEnd>, the statements between FOR and NEXT are no longer executed.

STEP <nIncrement>

<nIncrement> is a numeric value <nCounter> is incremented with for each iteration of the loop.

If not specified, it defaults to 1. When <nIncrement> is a negative value, the loop ends when

<nCounter> is smaller than or equal to <nEnd>.

EXIT

The EXIT statement unconditionally terminates a FOR...NEXT loop. Program flow branches to the first statement following the NEXT statement.

LOOP

The LOOP statement branches control unconditionally to the FOR statement, i.e. to the begin of the loop.

Description

The FOR...NEXT statements form a control structure that executes a block of statements for a specific number of times. This is controlled by the <nCounter> counter variable which gets assigned the value

<nStart> when the loop is entered for the first time. The loop iterates the statements between FOR and NEXT and adds the value <nIncrement> to <nCounter> each time the NEXT statement is reached or a LOOP statement is executed.

The value <nEnd> identifies the largest value for <nCounter> (<nIncrement> is positive) or its smallest value (<nIncrement> is negative) after which the FOR...NEXT loop terminates.

Note: The expressions in the FOR statement are evaluated each time a new iteration begins. As a consequence, new values can be assigned to <nCounter> or <nEnd> while the loop executes.

FOR

Info

See also: AEval(),FOR EACH,DO CASE,DO WHILE,IF,SWITCH,WITH OBJECT Category: Control structures,Statements

Example

// This example shows a typical scenario for a FOR..NEXT loop // where an array is filled with data, and stored data is output.

PROCEDURE Main LOCAL aFields, i USE Customer

aFields := Array( FCount() ) // fill array in regular order FOR i:=1 TO FCount()

aArray[i] := FieldName(i) NEXT

USE

// output data in reverse order FOR i:=Len( aArray ) TO 1 STEP -1

? aArray[i]

NEXT RETURN

In document xHarbour Language Reference Guide (Page 127-134)