File Coverage

blib/lib/Range/ArrayIter.pm
Criterion Covered Total %
statement 46 47 97.8
branch 18 20 90.0
condition 4 5 80.0
subroutine 9 9 100.0
pod 1 1 100.0
total 78 82 95.1


line stmt bran cond sub pod time code
1             package Range::ArrayIter;
2              
3             our $DATE = '2019-04-23'; # DATE
4             our $VERSION = '0.002'; # VERSION
5              
6 1     1   65819 use strict;
  1         12  
  1         30  
7 1     1   6 use warnings;
  1         2  
  1         31  
8              
9 1     1   5 use Exporter qw(import);
  1         2  
  1         121  
10             our @EXPORT_OK = qw(range_arrayiter);
11              
12             sub range_arrayiter($$;$) {
13 7     7 1 3505 my ($start, $end, $step) = @_;
14              
15 7         28 tie my @ary, 'Range::ArrayIter::Tie', $start, $end, $step;
16 7         32 \@ary;
17             }
18              
19             package # hide from PAUSE
20             Range::ArrayIter::Tie;
21              
22 1     1   8 use Scalar::Util qw(looks_like_number);
  1         16  
  1         703  
23              
24             sub TIEARRAY {
25 7     7   15 my $class = shift;
26 7         12 my ($start, $end, $step) = @_;
27 7   100     33 $step //= 1;
28              
29 7         32 my $self = {
30             start => $start,
31             end => $end,
32             step => $step,
33              
34             _ended => 0,
35             _len => 0,
36             _cur => $start,
37             _buf => [],
38             };
39              
40 7 100 66     37 if (looks_like_number($start) && looks_like_number($end)) {
41 4         14 $self->{_num} = 1;
42 4 100       10 $self->{_ended}++ if $start > $end;
43             } else {
44 3 50       8 die "Cannot specify step != 1 for non-numeric range" if $step != 1;
45 3 100       10 $self->{_ended}++ if $start gt $end;
46             }
47 7         21 bless $self, $class;
48             }
49              
50             sub _next {
51 43     43   57 my $self = shift;
52              
53 43 100       80 if ($self->{_num}) {
54 13 100       28 $self->{_ended}++ if $self->{_cur} > $self->{end};
55 13 100       27 return if $self->{_ended};
56 9         12 push @{ $self->{_buf} }, $self->{_cur};
  9         16  
57 9         31 $self->{_cur} += $self->{step};
58             } else {
59 30 100       51 return if $self->{_ended};
60 27 100       47 $self->{_ended}++ if $self->{_cur} ge $self->{end};
61 27         32 push @{ $self->{_buf} }, $self->{_cur}++;
  27         65  
62             }
63             }
64              
65             sub FETCHSIZE {
66 43     43   89 my $self = shift;
67 43         79 $self->_next;
68 43         58 $self->{_len} + @{ $self->{_buf} };
  43         104  
69             }
70              
71             sub FETCH {
72 36     36   129 my $self = shift;
73 36 50       42 if (@{ $self->{_buf} }) {
  36         62  
74 36         47 $self->{_len}++;
75 36         40 shift @{ $self->{_buf} };
  36         106  
76             } else {
77 0           undef;
78             }
79             }
80              
81             1;
82             # ABSTRACT: Generate a tied-array iterator for range
83              
84             __END__