File:  [LON-CAPA] / loncom / types / HashIterator.pm
Revision 1.1: download - view: text, annotated - select for diffs
Fri Apr 18 02:40:24 2003 UTC (21 years, 1 month ago) by foxr
Branches: MAIN
CVS tags: HEAD
Move these type implementing classes to the mainline cvs from the experimental
sandbox.

    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>