"Next! Next! Next! Next!"
Iterator
An iterator is a way to traverse a collection of objects without care about underline details. So, if you have a collection of strings, or a collections of Customers, or even a collection of records and all that you want to do is to get one by one sequentially using a unified model, what you need is an iterator.
UML diagram

The diagram above depict the basic idea of an iterator. A client class (or just a procedural program) creates a collection using ConcreteAggregate class, then an Iterator is created receiving the newly created collection. The iterator allows you to retrieve each element in the collection ordered by the index.
There are too many uses for iterators, including using the collection to hold data from a database query, and the iterator to taverse that collection when generating a report, for example.
Code
Lets see some action. Below is the code that use the iterator:
1: IDENTIFICATION DIVISION.
2: PROGRAM-ID. MAIN AS "ConsoleApplication1.Main".
3: ENVIRONMENT DIVISION.
4: CONFIGURATION SECTION.
5: SPECIAL-NAMES.
6: REPOSITORY.
7: class ClassConcreteAggregate as "IteratorPattern.ConcreteAggregate"
8: class ClassConcreteIterator as "IteratorPattern.ConcreteIterator"
9: class ClassObject as "System.Object"
10: class ClassSystemConsole as "System.Console".
11:
12: DATA DIVISION.
13: WORKING-STORAGE SECTION.
14: 01 array usage object reference ClassConcreteAggregate.
15: 01 item usage object reference ClassObject.
16: 01 iteratorusage object reference ClassConcreteIterator.
17:
18: PROCEDURE DIVISION.
19: invoke ClassConcreteAggregate "NEW" returning array
20:
21: invoke array "SetItem" using 0 "Item a"
22: invoke array "SetItem" using 1 "Item b"
23: invoke array "SetItem" using 2 "Item c"
24: invoke array "SetItem" using 3 "Item d"
25: invoke ClassConcreteIterator "NEW" using array returning iterator
26:
27: display "Iterating over collection:"
28:
29: set item to iterator::"First"()
30:
31: perform until item = null
32: invoke ClassSystemConsole "WriteLine" using item
33:
34: set item to iterator::"Next"()
35: end-perform
36: END PROGRAM MAIN.
Running the code above a collection is created with four strings, but it could be anything. The iteration occurs within the PERFORM verb block. The result is the following:
Item a
Item b
Item c
Item d
The ConcreteAggregate class contains the collection created with the "SetItem" method. That collection is an ArrayList object, so the element can be anything (alphanumeric items, numeric, numeric edited, objects, anything). An element can also be updated through the very same SetItem method.
1: CLASS-ID. ConcreteAggregate as "IteratorPattern.ConcreteAggregate" inherits ClassAbstractAggregate.
2: environment division.
3: configuration section.
4: repository.
5: class ClassAbstractAggregate as "IteratorPattern.AbstractAggregate"
6: class ClassAbstractIterator as "IteratorPattern.Iterator"
7: class ClassConcreteIterator as "IteratorPattern.ConcreteIterator"
8: class ClassArrayList as "System.Collections.ArrayList"
9: class ClassObject as "System.Object"
10:
11: property ArrayCount as "Count".
12:
13: object.
14: data division.
15: working-storage section.
16: copy "Types.Book".
17:
18: 01 _items usage object reference ClassArrayList.
19:
20:
21: procedure division.
22: method-id. NEW.
23: procedure division.
24: invoke ClassArrayList "NEW" returning _items
25:
26: end method NEW.
27:
28: method-id. CreateIterator as "CreateIterator" override.
29: data division.
30: linkage section.
31: 01 outIterator usage object reference ClassAbstractIterator.
32:
33: procedure division returning outIterator.
34: invoke ClassConcreteIterator "NEW" using SELF returning outIterator
35:
36: end method CreateIterator.
37:
38: method-id. CountItems as "Count".
39: data division.
40: linkage section.
41: 01 outCount type SystemInt32.
42:
43: procedure division returning outCount.
44: move ArrayCount of _items to outCount
45:
46: end method CountItems.
47:
48: method-id. GetItem as "GetItem".
49: data division.
50: linkage section.
51: 01 inIndex type SystemInt32.
52: 01 outObject usage object reference ClassObject.
53:
54: procedure division using inIndex returning outObject.
55:
56: invoke _items "Get_Item" using inIndex returning outObject
57:
58: end method GetItem.
59: method-id. SetItem as "SetItem".
60: data division.
61: linkage section.
62: 01 inIndextype SystemInt32.
63: 01 inObject usage object reference ClassObject.
64:
65: procedure division using inIndex inObject.
66:
67: invoke _items "Insert" using inIndex inObject
68:
69: end method SetItem.
70:
71: end object.
72: END CLASS ConcreteAggregate.
This pattern implementation requires the index of the item, but you could get rid of it by controlling it internally. It is up to you!
Next we got the Iterator class that is created receiving the collection represented by the "array" variable (ConcreteAggregate):
1: CLASS-ID. ConcreteIterator as "IteratorPattern.ConcreteIterator" inherits ClassAbstractIterator.
2: environment division.
3: configuration section.
4: repository.
5: class ClassObject as "System.Object"
6: class ClassAbstractIterator as "IteratorPattern.Iterator"
7: class ClassConcreteAggregate as "IteratorPattern.ConcreteAggregate".
8:
9: object.
10: data division.
11: working-storage section.
12: copy "types.book".
13:
14: 01 _currenttype SystemInt32.
15: 01 _aggregate usage object reference ClassConcreteAggregate private.
16: procedure division.
17: method-id. NEW.
18: data division.
19: linkage section.
20: 01 inAggregate usage object reference ClassConcreteAggregate.
21:
22: procedure division using inAggregate.
23: set _aggregate to inAggregate
24:
25: end method NEW.
26:
27: method-id. FirstItem as "First" override.
28: data division.
29: linkage section.
30: 01 outItem usage object reference ClassObject.
31:
32: procedure division returning outItem.
33: move zeros to _current
34:
35: set outItem to _aggregate::"GetItem"(0)
36:
37: end method FirstItem.
38:
39: method-id. NextItem as "Next" override.
40: data division.
41: linkage section.
42: 01 outItem usage object reference ClassObject.
43:
44: procedure division returning outItem.
45: if (_current < _aggregate::"Count"() - 1)
46: add 1 to _current
47: set outItem to _aggregate::"GetItem" (_current)
48: end-if
49: end method NextItem.
50:
51: method-id. CurrentItem as "CurrentItem" override.
52: data division.
53: linkage section.
54: 01 outItem usage object reference ClassObject.
55:
56: procedure division returning outItem.
57:
58: set outItem to _aggregate::"GetItem"(_current)
59:
60:
61: end method CurrentItem.
62:
63: method-id. IsDone as "IsDone" override.
64: data division.
65: linkage section.
66: 01 outStatus pic 1. *> boolean
67:
68: procedure division returning outStatus.
69:
70: if (_current >= _aggregate::"Count"())
71: move b"1" to outStatus
72: else
73: move b"0" to outStatus
74: end-if
75:
76: end method IsDone.
77:
78: end object.
79: END CLASS ConcreteIterator.
The Iterator Pattern has immediate usage in your application. It is a way to implement a "foreach" statement in Cobol, but as a matter of fact it is not the only way to do this! You can also use the PERFORM verb :
PERFORM VARYING identifier-1 THROUGH identifier-2
END-PERFORM
Identifier-1 must be a data item.
Identifier-2 must be a object-identifier that identifies a data collection. However, it must not be a predefined object identifier.
The type of the object identifier specified for identifier-2 must be one of the following:
a. A type that implements the System.Collections.IEnumerable interface.
b. A type that implements the System.Collections.Generic.IEnumerable interface.
c. A type that satisfies the following conditions:
- The type has an accessible instance method named GetEnumerator. The GetEnumerator method does not have arguments and returns a type T.
- The type T that contains the accessible instance method named MoveNext.
The MoveNext method does not have arguments and returns a Boolean type.
- The type T contains the accessible instance property named Current. The Current property has a get accessor.
Example:
01 aString pic x(20).
01 collection usage object reference ClassArrayList.
invoke ClassArrayList "NEW" returning collection
invoke collection "Add" using "item 1"
invoke collection "Add" using "item 2"
invoke collection "Add" using "item 3"
invoke collection "Add" using "item 4"
perform varying aString through collection
display aString
end-perform
Download the source
http://cobolrocks.codeplex.com/SourceControl/changeset/view/58694#
Some references in the web
http://www.dofactory.com/Patterns/PatternIterator.aspx
http://en.wikipedia.org/wiki/Iterator