File Coverage

blib/lib/Array/Circular.pm
Criterion Covered Total %
statement 53 56 94.6
branch 16 22 72.7
condition n/a
subroutine 12 13 92.3
pod 8 8 100.0
total 89 99 89.9


line stmt bran cond sub pod time code
1 3     3   1086 use strict;
  3         14  
  3         68  
2 3     3   81 use warnings;
  3         4  
  3         87  
3             package Array::Circular;
4             # ABSTRACT: Provide an array data structure that can go around in circles
5              
6 3     3   12 use Carp;
  3         4  
  3         224  
7 3     3   14 use Scalar::Util qw/refaddr/;
  3         19  
  3         1829  
8              
9             my %DATA;
10              
11             sub new {
12 3     3 1 307 my ($class, @self) = @_;
13 3         8 my $self = bless \@self, $class;
14 3         16 $self->me( { current => 0, count => 0 } );
15 3         6 return $self;
16             }
17              
18             sub me {
19 183     183 1 705 my ($self, $args) = @_;
20 183         305 my $loc = refaddr $self;
21 183 100       272 $DATA{$loc} = $args if $args;
22 183         471 return $DATA{$loc};
23             }
24              
25             sub current {
26 12     12 1 3840 my ($self) = @_;
27 12         38 return $self->[ $self->me->{current} ];
28             }
29              
30             *curr = \¤t;
31              
32             sub index {
33 0     0 1 0 my ($self, $idx) = @_;
34 0 0       0 $self->me->{current} = $idx if defined $idx;
35 0         0 return $self->me->{current};
36             }
37              
38             sub loops {
39 19     19 1 36 my ($self, $new_ct) = @_;
40 19 50       40 $self->me->{count} = $new_ct if defined $new_ct;
41 19         30 return $self->me->{count};
42             }
43              
44             sub next {
45 34     34 1 9339 my ($self, $num) = @_;
46 34 100       87 return unless @$self;
47              
48 24 100       37 if ($num) {
49 1 50       3 carp "Calls to next with a count of how many to go forward must be a positive number" if $num < 0;
50 1         1 $num--;
51 1         5 $self->next for 1 .. $num; # This is inefficient but simple. Could use $self->me to compute where we are as optimisation
52             }
53              
54              
55 24         24 my $last_index = $#{$self};
  24         35  
56 24 100       40 if ( $self->me->{current} == $last_index ) {
57 13         27 $self->me->{current} = -1;
58 13         27 $self->me->{count}++;
59             }
60 24         43 return $self->[ ++ $self->me->{current} ];
61             }
62              
63             sub previous {
64 16     16 1 2610 my ($self, $num) = @_;
65 16 50       32 return unless @$self;
66              
67 16 100       26 if ($num) {
68 1 50       3 carp "Calls to next with a count of how many to go forward must be a positive number" if $num < 0;
69 1         1 $num--;
70 1         5 $self->previous for 1 .. $num; # This is inefficient but simple. Could use $self->me to compute where we are as optimisation
71             }
72              
73 16 100       26 if ( $self->me->{current} == 0 ) {
74 5         11 $self->me->{current} = scalar(@$self);
75 5         17 $self->me->{count}--;
76              
77             }
78 16         27 return $self->[ -- $self->me->{current} ];
79             }
80              
81             *prev = \&previous;
82              
83             sub reset {
84 1     1 1 3 my ($self) = @_;
85 1         2 $self->me->{current} = 0;
86 1         3 $self->me->{count} = 0;
87 1         2 return $self->current;
88             }
89              
90             sub DESTROY {
91 3     3   3924 my $self = shift;
92 3         322 delete $DATA{refaddr $self};
93             }
94              
95             1;
96              
97             __END__