-
Notifications
You must be signed in to change notification settings - Fork 206
/
foreach2.prg
105 lines (90 loc) · 2.79 KB
/
foreach2.prg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
* demonstration code for FOR EACH overloading
*
* Copyright 2007 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
*
*/
#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 can set it using (@enum):__enumIndex( nNeIndex )
* message
*/
return .T. /* continue iteration */
METHOD PROCEDURE __enumStop() CLASS myclass2
/* Here we can have cleanup code */
return