NAME
Module::Generic::Iterator - An Array Iterator Object Class
SYNOPSIS
my $i = Module::Generic::Iterator->new( [qw( Joe John Mary )] );
# or also:
my $a = Module::Generic::Array->new( [qw( Joe John Mary )] );
my $i = $a->iterator;
while( $i->has_next )
{
my $elem = $i->next;
my $value = $elem->value;
# Get the next element relative to our element
printf( "Next value is: %s at offset %d\n", $elem->next, $elem->next->pos );
}
# Navigate to a specific element
my $elem = $iter->find( "Jack" );
print( "Found Jack at position: ", $elem->pos, "\n" );
# Use element navigation
my $first = $iter->first;
my $next = $first->next; # Returns "Jack" as an element
print( "Next after John: ", $next->value, "\n" );
VERSION
v1.2.3
DESCRIPTION
Module::Generic::Iterator provides a generic iterator interface for traversing a list of elements. It supports navigation through the list with methods like "next", "prev", "first", and "last", and allows finding specific elements with "find". Each element in the iterator is wrapped in a Module::Generic::Iterator::Element object, which provides contextual navigation (e.g., "next", "prev") relative to the parent iterator.
This class is designed to be lightweight and flexible, working with any array of values, including scalars, references, or objects.
CONSTRUCTORS
new
Creates a new iterator object. It takes an optional array reference or an Module::Generic::Array object of elements to iterate over, and an optional hash or hash reference of parameters, and returns the newly instantiated object:
my $iter = Module::Generic::Iterator->new( [1, 2, 3], debug => 3 );
Supported parameters:
debug
An integer to enable debugging. See "debug" in Module::Generic.
Returns a new Module::Generic::Iterator object.
METHODS
elements
Returns the underlying array of elements as a Module::Generic::Array object. Each element is a Module::Generic::Iterator::Element object:
my $elems = $iter->elements;
print( $elems->length, "\n" ); # Number of elements
eof
Returns true if the iterator is at the end of the list (i.e., the current position is the last element or beyond). Optionally takes an element to check its position:
if( $iter->eof )
{
print( "End of iterator\n" );
}
find
Finds an element by value and returns its corresponding Module::Generic::Iterator::Element object. Returns undef
in scalar context, or an empty list in list context if the element is not found:
my $elem = $iter->find( "Jack" );
print( $elem->value, "\n" ) if( $elem ); # "Jack"
For reference values, comparison is done using "refaddr" in Scalar::Util. For scalar values, comparison is done using string equality (eq
).
first
Moves the iterator to the first element and returns it as a Module::Generic::Iterator::Element object:
my $first = $iter->first;
print( $first->value, "\n" ); # First element
has_next
Returns true if there is a next element in the iterator:
while( $iter->has_next )
{
my $elem = $iter->next;
print( $elem->value, "\n" );
}
has_prev
Returns true if there is a previous element in the iterator:
$iter->last;
if( $iter->has_prev )
{
my $prev = $iter->prev;
print( $prev->value, "\n" );
}
last
Moves the iterator to the last element and returns it as a Module::Generic::Iterator::Element object:
my $last = $iter->last;
print( $last->value, "\n" ); # Last element
length
Returns the number of elements, starting from 1, as a Module::Generic::Number object.
print( $iter->length, "\n" ); # e.g., 5
next
Moves the iterator to the next element and returns it as a Module::Generic::Iterator::Element object. Optionally takes an element to start from:
while( my $elem = $iter->next )
{
print( $elem->value, "\n" );
}
Returns undef
in scalar context, or an empty list in list context, if there are no more elements.
pos
An lvalue method to get or set the current position in the iterator. Returns the position as an integer:
$iter->pos = 2; # Move to the third element
my $pos = $iter->pos; # Returns the current position
print( $iter->pos, "\n" ); # 2
Warns if the position is not an integer.
prev
Moves the iterator to the previous element and returns it as a Module::Generic::Iterator::Element object. Optionally takes an element to start from:
$iter->last;
my $prev = $iter->prev;
print( $prev->value, "\n" );
Returns undef
in scalar context, or an empty list in list context, if there are no previous elements.
reset
Resets the iterator position to the beginning (position 0):
$iter->last;
$iter->reset;
print( $iter->pos, "\n" ); # 0
Returns the iterator object.
_find_pos
Provided with an item, this returns its position in the array or undef if it is not in the array.
SERIALISATION
Serialisation by CBOR, Sereal and Storable::Improved (or the legacy Storable) is supported by this package. To that effect, the following subroutines are implemented: FREEZE
, THAW
, STORABLE_freeze
and STORABLE_thaw
THREAD-SAFETY
Module::Generic::Iterator is thread-safe for all operations, as it operates on per-object state and does not modify shared resources at runtime.
Key considerations for thread-safety:
Shared Variables
There are no shared variables that are modified at runtime. The global
$DEBUG
variable (inherited from Module::Generic) is typically set before threads are created, and it is the user's responsibility to ensure thread-safety if modified at runtime:use threads; local $Module::Generic::Iterator::DEBUG = 0; # Set before threads my @threads = map { threads->create(sub { my $iter = Module::Generic::Iterator->new( [1, 2, 3] ); $iter->next; # Thread-safe }); } 1..5; $_->join for( @threads );
Object State
Iterator data (e.g., "elements", "pos", "value" in Module::Generic::Iterator::Element) is stored per-object, ensuring thread isolation:
use threads; my @threads = map { threads->create(sub { my $iter = Module::Generic::Iterator->new( [1, 2, 3] ); while( my $elem = $iter->next ) { print( $elem->value, "\n" ); # Thread-safe } }); } 1..5; $_->join for( @threads );
Serialisation
Serialisation methods ("FREEZE", "THAW") operate on per-object state, making them thread-safe.
For debugging in threaded environments (depending on your Operating System):
ls -l /proc/$$/fd # List open file descriptors
SEE ALSO
Module::Generic::Iterator::Element, Module::Generic::Array
AUTHOR
Jacques Deguest <jack@deguest.jp>
COPYRIGHT & LICENSE
Copyright (c) 2000-2024 DEGUEST Pte. Ltd.
You can use, copy, modify and redistribute this package and associated files under the same terms as Perl itself.