File Coverage

blib/lib/Iterator/Flex/Sequence.pm
Criterion Covered Total %
statement 84 85 98.8
branch 32 34 94.1
condition 8 12 66.6
subroutine 20 21 95.2
pod 1 2 50.0
total 145 154 94.1


line stmt bran cond sub pod time code
1             package Iterator::Flex::Sequence;
2              
3             # ABSTRACT: Numeric Sequence Iterator Class
4              
5 10     10   318662 use v5.28;
  10         47  
6 10     10   62 use strict;
  10         21  
  10         322  
7 10     10   77 use warnings;
  10         24  
  10         678  
8 10     10   643 use experimental 'signatures', 'postderef';
  10         2076  
  10         142  
9              
10             our $VERSION = '0.33';
11              
12 10     10   2922 use Scalar::Util;
  10         55  
  10         609  
13 10     10   59 use List::Util;
  10         19  
  10         741  
14              
15 10     10   63 use parent 'Iterator::Flex::Base';
  10         32  
  10         118  
16 10     10   1006 use Iterator::Flex::Utils qw( STATE :IterAttrs throw_failure );
  10         24  
  10         2543  
17              
18 10     10   83 use namespace::clean;
  10         20  
  10         151  
19              
20              
21              
22              
23              
24              
25              
26              
27              
28              
29              
30              
31              
32              
33              
34              
35              
36              
37              
38              
39              
40              
41              
42              
43              
44              
45              
46              
47              
48              
49              
50              
51              
52              
53 67     67 1 183 sub new ( $class, @args ) {
  67         169  
  67         165  
  67         153  
54              
55 67 100       305 my $pars = Ref::Util::is_hashref( $args[-1] ) ? pop @args : {};
56              
57 67 50 33     533 throw_failure( parameter => q{incorrect number of arguments for sequence} )
58             if @args < 1 || @args > 3;
59              
60 67         149 my %state;
61 67 100       277 $state{step} = pop @args if @args == 3;
62 67         247 $state{end} = pop @args;
63 67         169 $state{begin} = pop @args;
64              
65              
66 67         431 $class->SUPER::new( \%state, $pars );
67             }
68              
69 75     75 0 164 sub construct ( $class, $state ) {
  75         164  
  75         141  
  75         128  
70              
71             throw_failure( parameter => "$class: arguments must be numbers\n" )
72 75 50   0   764 unless List::Util::all { Scalar::Util::looks_like_number( $_ ) };
  0         0  
73              
74             my ( $begin, $end, $step, $iter, $next, $current, $prev )
75 75         380 = @{$state}{qw[ begin end step iter next current prev ]};
  75         403  
76              
77 75         252 my $self;
78             my $iterator_state;
79              
80 75         0 my %params;
81              
82 75 100       245 if ( !defined $step ) {
83              
84 67 100       209 $begin = 0 unless defined $begin;
85 67 100       212 $next = $begin unless defined $next;
86              
87             %params = (
88             ( +NEXT ) => sub {
89 1032 100   1032   2295 if ( $next > $end ) {
90 100 100       365 $prev = $current
91             unless $self->is_exhausted;
92 100         389 return $current = $self->signal_exhaustion;
93             }
94 932         1430 $prev = $current;
95 932         1424 $current = $next++;
96 932         2410 return $current;
97             },
98             ( +FREEZE ) => sub {
99             return [
100 26     26   139 $class,
101             {
102             begin => $begin,
103             end => $end,
104             prev => $prev,
105             current => $current,
106             next => $next,
107             },
108             ];
109             },
110 67         602 );
111             }
112              
113             else {
114              
115 8 100 100     91 throw_failure(
      66        
      66        
116             parameter => q{sequence will be inifinite as $step is zero or has the incorrect sign} )
117             if ( $begin < $end && $step <= 0 ) || ( $begin > $end && $step >= 0 );
118              
119 7 100       99 $next = $begin unless defined $next;
120 7 100       22 $iter = 0 unless defined $iter;
121              
122             %params = (
123             ( +FREEZE ) => sub {
124             return [
125 1     1   13 $class,
126             {
127             begin => $begin,
128             end => $end,
129             step => $step,
130             iter => $iter,
131             prev => $prev,
132             current => $current,
133             next => $next,
134             },
135             ];
136             },
137              
138             ( +NEXT ) => $begin < $end
139             ? sub {
140 33 100   33   110 if ( $next > $end ) {
141 16 100       60 $prev = $current
142             unless $self->is_exhausted;
143 16         56 return $current = $self->signal_exhaustion;
144             }
145 17         30 $prev = $current;
146 17         29 $current = $next;
147 17         60 $next = $begin + ++$iter * $step;
148 17         74 return $current;
149             }
150             : sub {
151 8 100   8   53 if ( $next < $end ) {
152 4 100       19 $prev = $current
153             unless $self->is_exhausted;
154 4         19 return $current = $self->signal_exhaustion;
155             }
156 4         8 $prev = $current;
157 4         7 $current = $next;
158 4         10 $next = $begin + ++$iter * $step;
159 4         22 return $current;
160             },
161 7 100       82 );
162             }
163              
164             return {
165             %params,
166 106     106   324 ( +CURRENT ) => sub { $current },
167 105     105   296 ( +PREV ) => sub { $prev },
168             ( +REWIND ) => sub {
169 19     19   206 $next = $begin;
170 19         43 $iter = 0;
171             },
172             ( +RESET ) => sub {
173 28     28   64 $prev = $current = undef;
174 28         52 $next = $begin;
175 28         64 $iter = 0;
176             },
177              
178 74         1520 ( +_SELF ) => \$self,
179              
180             ( +STATE ) => \$iterator_state,
181             };
182              
183             }
184              
185             __PACKAGE__->_add_roles( qw[
186             State::Closure
187             Next::ClosedSelf
188             Rewind::Closure
189             Reset::Closure
190             Prev::Closure
191             Current::Closure
192             Freeze
193             ] );
194              
195             1;
196              
197             #
198             # This file is part of Iterator-Flex
199             #
200             # This software is Copyright (c) 2018 by Smithsonian Astrophysical Observatory.
201             #
202             # This is free software, licensed under:
203             #
204             # The GNU General Public License, Version 3, June 2007
205             #
206              
207             __END__