List::Cycle - Objects for cycling through a list of values


List-Cycle documentation Contained in the List-Cycle distribution.

Index


Code Index:

NAME

Top

List::Cycle - Objects for cycling through a list of values

VERSION

Top

Version 1.00

SYNOPSIS

Top

List::Cycle gives you an iterator object for cycling through a series of values. The canonical use is for cycling through a list of colors for alternating bands of color on a report.

    use List::Cycle;

    my $colors = List::Cycle->new( {values => ['#000000', '#FAFAFA', '#BADDAD']} );
    print $colors->next; # #000000
    print $colors->next; # #FAFAFA
    print $colors->next; # #BADDAD
    print $colors->next; # #000000
    print $colors->next; # #FAFAFA
    ... etc ...

You'd call it at the top of a loop:

    while ( ... ) {
        my $color = $colors->next;
        print qq{<tr bgcolor="$color">;
        ...
    }

Note that a List::Cycle object is not a standard Perl blessed hash. It's an inside-out object, as suggested in Perl Best Practices. In the five years since PBP has come out, inside-out objects have been almost universally ignored, but I keep List::Cycle as an example. If you don't care about the internals of the object, then List::Cycle is a fine module for you to use.

FUNCTIONS

Top

new( {values => \@values} )

Creates a new cycle object, using @values.

The values keyword can be vals, if you like.

$cycle->set_values(\@values)

Sets the cycle values and resets the internal pointer.

$cycle->reset

Sets the internal pointer back to the beginning of the cycle.

    my $color = List::Cycle->new( {values => [qw(red white blue)]} );
    print $color->next; # red
    print $color->next; # white
    $color->reset;
    print $color->next; # red, not blue

$cycle->dump

Returns a handy string representation of internals.

$cycle->next

Gives the next value in the sequence.

AUTHOR

Top

Andy Lester, <andy at petdance.com>

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc List::Cycle

You can also look for information at:

* AnnoCPAN: Annotated CPAN documentation

http://annocpan.org/dist/List-Cycle

* CPAN Ratings

http://cpanratings.perl.org/d/List-Cycle

* RT: CPAN's request tracker

http://rt.cpan.org/NoAuth/Bugs.html?Dist=List-Cycle

* Search CPAN

http://search.cpan.org/dist/List-Cycle

* Source code repository

http://github.com/petdance/list-cycle

BUGS

Top

Please report any bugs or feature requests to bug-list-cycle @ rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=List-Cycle. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

ACKNOWLEDGEMENTS

Top

List::Cycle is a playground that uses some of the ideas in Damian Conway's marvelous Perl Best Practices. http://www.oreilly.com/catalog/perlbp/ One of the chapters mentions a mythical List::Cycle module, so I made it real.

Thanks also to Ricardo SIGNES and Todd Rinaldo for patches.

COPYRIGHT & LICENSE

Top


List-Cycle documentation Contained in the List-Cycle distribution.
package List::Cycle;

use warnings;
use strict;
use Carp ();

our $VERSION = '1.00';

my %storage = (
    values  => \my %values_of,
    pointer => \my %pointer_of,
);

sub new {
    my $class = shift;
    my $args = shift;

    my $self = \do { my $scalar };
    bless $self, $class;

    $self->_init( %$args );

    return $self;
}

sub _init {
    my $self = shift;
    my @args = @_;

    $self->_store_pointer( 0 );
    while ( @args ) {
        my $key = shift @args;
        my $value = shift @args;

        if ( $key =~ /^val(ue)?s$/ ) {
            $self->set_values($value);
        }
        else {
            Carp::croak( "$key is not a valid constructor value" );
        }
    }

    return $self;
}

sub set_values {
    my ($self, $values) = @_;

    $values_of{ $self } = $values;
    $self->reset;
}

sub DESTROY {
    my $self = shift;

    for my $attr_ref ( values %storage ) {
        delete $attr_ref->{$self};
    }

    return;
}

sub _pointer {
    my $self = shift;

    return $pointer_of{ $self };
}

sub _store_pointer {
    my $self = shift;

    $pointer_of{ $self } = shift;

    return;
}

sub _inc_pointer {
    my $self = shift;
    my $ptr  = $self->_pointer;
    $self->_store_pointer(($ptr+1) % @{$values_of{$self}});

    return;
}

sub reset {
    my $self = shift;

    $self->_store_pointer(0);

    return;
}

sub dump {
    my $self = shift;
    my $str = "";

    while ( my($key,$value) = each %storage ) {
        my $realval = $value->{$self};
        $realval = join( ",", @$realval ) if UNIVERSAL::isa( $realval, "ARRAY" );
        $str .= "$key => $realval\n";
    }
    return $str;
}

sub next {
    my $self = shift;

    Carp::croak( 'no cycle values provided!' ) unless $values_of{ $self };

    my $ptr = $self->_pointer;
    $self->_inc_pointer;
    return $values_of{ $self }[$ptr];
}