diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3debe44e6a..113a0d2d5d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,10 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ +2007-07-30 18:10 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + + harbour/tests/foreach2.prg + * added example for FOR EACH overloading + 2007-07-30 18:00 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbcompat.ch + added #xtranslate ISPOINTER( ) diff --git a/harbour/tests/foreach2.prg b/harbour/tests/foreach2.prg new file mode 100644 index 0000000000..1076f6b610 --- /dev/null +++ b/harbour/tests/foreach2.prg @@ -0,0 +1,111 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * demonstration code for FOR EACH overloading + * + * Copyright 2007 Przemyslaw Czerpak + * www - http://www.harbour-project.org + * + */ + + +#include "hbclass.ch" + +proc main() +local e, o + + ? "FOR EACH e IN myclass1()" + o:=myclass1() + for each e in o + ? e:__enumIndex(), "=>", e + next + ? "FOR EACH e IN myclass1() DESCEND" + for each e in o descend + ? e:__enumIndex(), "=>", e + next + + ? + ? "FOR EACH e IN myclass2()" + o:=myclass2() + for each e in o + ? e:__enumIndex(), "=>", e + next + ? "FOR EACH e IN myclass2() DESCEND" + for each e in o descend + ? e:__enumIndex(), "=>", e + next + +return + + +/* The first form of FOR EACH overloading + * Can be use when all values can be calculated when FOR EACH starts + * It overloads __enumStart() message which set base enumerator values. + * for ascending iteration it sets: {"A","B","C"} + * and for descending: {1, 2, 3} + */ +CREATE CLASS myclass1 + METHOD __enumStart( enum, lDescend ) +END CLASS + +METHOD __enumStart( enum, lDescend ) CLASS myclass1 + /* set base value for enumerator */ + /* important: the messages have to be send to the enumerator + * reference (@enum) not directly to the enumerator enum + */ + (@enum):__enumBase( iif( lDescend, {1, 2, 3}, {"A","B","C"} ) ) + return .T. /* .F. means stop iteration */ + + +/* The second form of FOR EACH overloading + * We are overloading the folowing messages: + * __enumStart() // executed when FOR EACH starts + * __enumSkip() // executed on each LOOP + * __enumStop() // executed when FOR EACH stops + * Such method can be used when we cannot calculate all values + * when FOR EACH starts or such calculation is expensive so we + * want to make them dynamically + */ + +CREATE CLASS myclass2 + VAR value + METHOD __enumStart( enum, lDescend ) + METHOD __enumSkip( enum, lDescend ) + METHOD __enumStop() +END CLASS + +METHOD __enumStart( enum, lDescend ) CLASS myclass2 + /* Here we can have initialization code */ + ::value := 0.00 + /* set enumerator value */ + (@enum):__enumValue( ::value ) + /* set enumerator index, to make it more funny for descend + * iterations we will use negative indexes ;-) + */ + (@enum):__enumIndex( iif( lDescend, -1, 1 ) ) + return .T. /* continue iteration */ + +METHOD __enumSkip( enum, lDescend ) CLASS myclass2 + if lDescend + ::value -= 3 + else + ::value += 3 + endif + /* stop iteration when abs( ::value ) > 20 */ + if abs( ::value ) > 20 + return .F. + endif + /* set enumerator value */ + (@enum):__enumValue( ::value / 10.0 ) + /* the index is updated automatically but if we want some noncontinuous + * indexes then here we van set it using (@enum):__enumIndex( nNeIndex ) + * message + */ + return .T. /* continue iteration */ + +METHOD PROCEDURE __enumStop() CLASS myclass2 + /* Here we can have cleanup code */ + return