[LON-CAPA-cvs] cvs: loncom /types HashIterator.pm Queue.pm Stack.pm
foxr
lon-capa-cvs@mail.lon-capa.org
Fri, 18 Apr 2003 02:40:24 -0000
foxr Thu Apr 17 22:40:24 2003 EDT
Added files:
/loncom/types HashIterator.pm Queue.pm Stack.pm
Log:
Move these type implementing classes to the mainline cvs from the experimental
sandbox.
Index: loncom/types/HashIterator.pm
+++ loncom/types/HashIterator.pm
#
# Implement iteration over a opaque hash.
#
=pod
=head1 HashIterator
A hash iterator is an object that alows iteration over a hash in a
manner analagous to the way that STL iterators allow iteration over
those containers. The HashIterator has the effect of hiding the
existence of the hash from the caller and instead presenting an
iteratable collection to the caller.
The intent is for a hash iterator to be an object returned by another
object or class to support iteration over some internal hash
maintained by the object. Passing the hash itself back breaks data
hiding and protection.
=head1 Typical usage:
use HashIterator;
..
$i = HashIterator::new(\%myhash);
..
$i->begin();
while(! $i->end()) {
$itemref = $i->get();
$i->next();
}
=head1 Member Functions:
=cut
package HashIterator;
=pod
=head2 new(hash)
Create a new HashIterator object and return a reference to it. Data
members of the HashIterator include:
=over 4
=item Hash
Reference to the hash being iterated over.
=item Keylist
The set of keys in the underlying hash (an anonymous array ref).
=item KeyCount
The number of keys in the underlying hash.
=item Index
Position of the iterator within the keylist/hash table.
=back
=cut
sub new {
my $class = shift; # Class name...
my $hashref = shift; # Maintain this hash.
my @keylist = keys(%$hashref);
my $keyref= \@keylist;
my $keycount = scalar @keylist;
my $self = { Hash => $hashref,
Keylist => $keyref,
KeyCount => $keycount,
Index => 0};
bless($self, $class); # Type ourself...
return $self;
}
=pod
=head2 begin
Reset the iterator to the start of iteration.
=cut
sub begin {
my $self = shift; # Get object...
$self->{Index} = 0;
}
=pod
=head2 end
Return true if the iterator is off the end of the hash.
=cut
sub end {
my $self = shift; # Retrieve self as object.
return ($self->{Index} >= $self->{KeyCount});
}
=pod
=head2 get
Return the contents of the hash at the current key. If the key is off
the end of the hash, undef is returned. What is returned is a copy of
the element. If the index is off the end of the iteration, undef is
returned.
=cut
sub get {
my $self = shift;
if ($self->end()) {
return undef;
}
my $hashref = $self->{Hash};
my $key = $self->{Keylist}->[$self->{Index}];
return $$hashref{$key};
}
=pod
=head2 next
Advances the iterator.
=cut
sub next {
my $self = shift; # Get us.
$self->{Index} = $self->{Index} + 1;
}
1;
Index: loncom/types/Queue.pm
+++ loncom/types/Queue.pm
#
# Implement a simple queue in terms of a list.
#
=pod
=head1 Queue
An object oriented implementation of a queue data structure. queues
are first in last out data structures.
=head1 Member functions:
=cut
package Queue;
=pod
=head2 new
Construct a new queue.
=cut
sub new {
my $class = shift; # Class name to bless into.
my $self = []; # Our data is a reference to an anon. array.
bless($self, $class); # Type this as an object.
return $self;
}
=pod
=head2 enqueue
Add an element to the tail of the queue.
=cut
sub enqueue {
my $self = shift; # Get object reference.
my $item = shift; # Get the item to enqueue...
push(@$self, $item); # Push the item to the back of the array.
}
=pod
=head2 dequeue
Remove an element from the front of the queue.
=cut
sub dequeue {
my $self = shift; # Get object reference....
return shift @$self; # Remove from the front of the queue.
}
1;
=pod
=head1 Theory
The queue is implemented as an array... enqueue is a thinly disguised
push, and dequeue is a thinly disguised shift. This is probably quite
in efficient for large queues, but should be fine for reasonably sized
queues.
Note that since Perl is a dynamically typed language, queues can
contain objects of any data type and can even be heterogenously typed.
=cut
Index: loncom/types/Stack.pm
+++ loncom/types/Stack.pm
#
# Implement a simple stack in terms of a list.
#
=pod
=head1 Stack
An object oriented implementation of a Stack data structure.
Stacks are first in last out data structures.
=head1 Member functions:
=cut
package Stack;
=pod
=head2 new
Creates a new instance of a stack.
my $stack = Stack->new();
=cut
sub new {
my $class = shift; # Class name.
my $self = []; # Create an empty list to represent the stack.
bless($self, $class); # Turn this into an object and..
return $self; # Return it.
}
=pod
=head2 push
takes an item and pushes it onto the back end of the stack.
my $stack = Stack->new();
$stack->push(something);
=cut
sub push {
my $self = shift; # Gets the list...
my $item = shift; # The item to push.
push(@$self,$item);
}
=pod
=head2 pop
Returns the item at the top of the stack: does a pop.
my object = Stack->new();
my $item = object->pop();
=cut
sub pop {
my $self = shift;
return pop(@$self);
}
1;
=pod
=head1 Internal implementation details
Stacks are implemented as lists. Thus a stack is a thinly disguised
list with push and pop wrappers. Since PERL is a dynamically typed
language, stacks can contain any data type ... including a
heterogenous collection of types.
=cut