1: #
2: # Implement iteration over a opaque hash.
3: #
4:
5: =pod
6:
7: =head1 HashIterator
8:
9: A hash iterator is an object that alows iteration over a hash in a
10: manner analagous to the way that STL iterators allow iteration over
11: those containers. The HashIterator has the effect of hiding the
12: existence of the hash from the caller and instead presenting an
13: iteratable collection to the caller.
14:
15: The intent is for a hash iterator to be an object returned by another
16: object or class to support iteration over some internal hash
17: maintained by the object. Passing the hash itself back breaks data
18: hiding and protection.
19:
20: =head1 Typical usage:
21:
22: use HashIterator;
23: ...
24:
25: $i = HashIterator::new(\%myhash);
26:
27: ...
28:
29: $i->begin();
30: while(! $i->end()) {
31: $itemref = $i->get();
32: $i->next();
33: }
34:
35:
36: =head1 Member Functions:
37:
38: =cut
39:
40: package HashIterator;
41:
42: =pod
43:
44: =head2 new(hash)
45:
46: Create a new HashIterator object and return a reference to it. Data
47: members of the HashIterator include:
48:
49: =over 4
50:
51: =item Hash
52:
53: Reference to the hash being iterated over.
54:
55: =item Keylist
56:
57: The set of keys in the underlying hash (an anonymous array ref).
58:
59: =item KeyCount
60:
61: The number of keys in the underlying hash.
62:
63: =item Index
64:
65: Position of the iterator within the keylist/hash table.
66:
67: =back
68:
69: =cut
70:
71: sub new {
72: my $class = shift; # Class name...
73: my $hashref = shift; # Maintain this hash.
74: my @keylist = keys(%$hashref);
75: my $keyref= \@keylist;
76: my $keycount = scalar @keylist;
77:
78:
79: my $self = { Hash => $hashref,
80: Keylist => $keyref,
81: KeyCount => $keycount,
82: Index => 0};
83: bless($self, $class); # Type ourself...
84:
85: return $self;
86:
87: }
88:
89: =pod
90:
91: =head2 begin
92:
93: Reset the iterator to the start of iteration.
94:
95: =cut
96:
97: sub begin {
98: my $self = shift; # Get object...
99: $self->{Index} = 0;
100:
101: }
102:
103: =pod
104:
105: =head2 end
106:
107: Return true if the iterator is off the end of the hash.
108:
109: =cut
110:
111: sub end {
112: my $self = shift; # Retrieve self as object.
113: return ($self->{Index} >= $self->{KeyCount});
114: }
115:
116: =pod
117:
118: =head2 get
119:
120: Return the contents of the hash at the current key. If the key is off
121: the end of the hash, undef is returned. What is returned is a copy of
122: the element. If the index is off the end of the iteration, undef is
123: returned.
124:
125: =cut
126:
127: sub get {
128: my $self = shift;
129: if ($self->end()) {
130: return undef;
131: }
132: my $hashref = $self->{Hash};
133: my $key = $self->{Keylist}->[$self->{Index}];
134: return $$hashref{$key};
135: }
136:
137: =pod
138:
139: =head2 next
140:
141: Advances the iterator.
142:
143: =cut
144:
145: sub next {
146: my $self = shift; # Get us.
147: $self->{Index} = $self->{Index} + 1;
148: }
149:
150: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>