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   179099 use v5.28;
  10         30  
6 10     10   38 use strict;
  10         17  
  10         231  
7 10     10   33 use warnings;
  10         14  
  10         472  
8 10     10   399 use experimental 'signatures', 'postderef';
  10         1341  
  10         63  
9              
10             our $VERSION = '0.34';
11              
12 10     10   2004 use Scalar::Util;
  10         15  
  10         399  
13 10     10   44 use List::Util;
  10         17  
  10         448  
14              
15 10     10   39 use parent 'Iterator::Flex::Base';
  10         19  
  10         90  
16 10     10   639 use Iterator::Flex::Utils qw( STATE :IterAttrs throw_failure );
  10         17  
  10         1722  
17              
18 10     10   55 use namespace::clean;
  10         16  
  10         73  
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 77     77 1 115 sub new ( $class, @args ) {
  77         110  
  77         111  
  77         90  
54              
55 77 100       206 my $pars = Ref::Util::is_hashref( $args[-1] ) ? pop @args : {};
56              
57 77 50 33     378 throw_failure( parameter => q{incorrect number of arguments for sequence} )
58             if @args < 1 || @args > 3;
59              
60 77         107 my %state;
61 77 100       163 $state{step} = pop @args if @args == 3;
62 77         158 $state{end} = pop @args;
63 77         114 $state{begin} = pop @args;
64              
65              
66 77         313 $class->SUPER::new( \%state, $pars );
67             }
68              
69 85     85 0 91 sub construct ( $class, $state ) {
  85         109  
  85         93  
  85         92  
70              
71             throw_failure( parameter => "$class: arguments must be numbers\n" )
72 85 50   0   485 unless List::Util::all { Scalar::Util::looks_like_number( $_ ) };
  0         0  
73              
74             my ( $begin, $end, $step, $iter, $next, $current, $prev )
75 85         277 = @{$state}{qw[ begin end step iter next current prev ]};
  85         252  
76              
77 85         199 my $self;
78             my $iterator_state;
79              
80 85         0 my %params;
81              
82 85 100       173 if ( !defined $step ) {
83              
84 77 100       141 $begin = 0 unless defined $begin;
85 77 100       128 $next = $begin unless defined $next;
86              
87             %params = (
88             ( +NEXT ) => sub {
89 1036 100   1036   1320 if ( $next > $end ) {
90 101 100       226 $prev = $current
91             unless $self->is_exhausted;
92 101         236 return $current = $self->signal_exhaustion;
93             }
94 935         882 $prev = $current;
95 935         902 $current = $next++;
96 935         1365 return $current;
97             },
98             ( +FREEZE ) => sub {
99             return [
100 26     26   88 $class,
101             {
102             begin => $begin,
103             end => $end,
104             prev => $prev,
105             current => $current,
106             next => $next,
107             },
108             ];
109             },
110 77         417 );
111             }
112              
113             else {
114              
115 8 100 100     47 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       45 $next = $begin unless defined $next;
120 7 100       11 $iter = 0 unless defined $iter;
121              
122             %params = (
123             ( +FREEZE ) => sub {
124             return [
125 1     1   9 $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   76 if ( $next > $end ) {
141 16 100       33 $prev = $current
142             unless $self->is_exhausted;
143 16         31 return $current = $self->signal_exhaustion;
144             }
145 17         20 $prev = $current;
146 17         15 $current = $next;
147 17         25 $next = $begin + ++$iter * $step;
148 17         45 return $current;
149             }
150             : sub {
151 8 100   8   15 if ( $next < $end ) {
152 4 100       11 $prev = $current
153             unless $self->is_exhausted;
154 4         10 return $current = $self->signal_exhaustion;
155             }
156 4         6 $prev = $current;
157 4         5 $current = $next;
158 4         7 $next = $begin + ++$iter * $step;
159 4         15 return $current;
160             },
161 7 100       45 );
162             }
163              
164             return {
165             %params,
166 106     106   241 ( +CURRENT ) => sub { $current },
167 105     105   240 ( +PREV ) => sub { $prev },
168             ( +REWIND ) => sub {
169 19     19   27 $next = $begin;
170 19         30 $iter = 0;
171             },
172             ( +RESET ) => sub {
173 28     28   47 $prev = $current = undef;
174 28         52 $next = $begin;
175 28         45 $iter = 0;
176             },
177              
178 84         1006 ( +_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__