File Coverage

blib/lib/Range/ScalarIter.pm
Criterion Covered Total %
statement 37 37 100.0
branch 17 18 94.4
condition 4 5 80.0
subroutine 8 8 100.0
pod 1 1 100.0
total 67 69 97.1


line stmt bran cond sub pod time code
1             package Range::ScalarIter;
2              
3             our $DATE = '2019-05-12'; # DATE
4             our $VERSION = '0.001'; # VERSION
5              
6 1     1   66584 use strict;
  1         10  
  1         30  
7 1     1   5 use warnings;
  1         2  
  1         26  
8              
9 1     1   5 use Exporter qw(import);
  1         1  
  1         135  
10             our @EXPORT_OK = qw(range_scalariter);
11              
12             sub range_scalariter($$;$) {
13 7     7 1 3486 my ($start, $end, $step) = @_;
14              
15 7         27 tie my $scalar, 'Range::ScalarIter::Tie', $start, $end, $step;
16 7         30 \$scalar;
17             }
18              
19             package # hide from PAUSE
20             Range::ScalarIter::Tie;
21              
22 1     1   7 use Scalar::Util qw(looks_like_number);
  1         2  
  1         301  
23              
24             sub TIESCALAR {
25 7     7   15 my $class = shift;
26 7         16 my ($start, $end, $step) = @_;
27 7   100     36 $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         13 $self->{_num} = 1;
42 4 100       11 $self->{_ended}++ if $start > $end;
43             } else {
44 3 50       9 die "Cannot specify step != 1 for non-numeric range" if $step != 1;
45 3 100       22 $self->{_ended}++ if $start gt $end;
46             }
47 7         20 bless $self, $class;
48             }
49              
50             sub _next {
51 43     43   53 my $self = shift;
52              
53 43 100       76 if ($self->{_num}) {
54 13 100       23 $self->{_ended}++ if $self->{_cur} > $self->{end};
55 13 100       29 return if $self->{_ended};
56 9         13 my $res = $self->{_cur};
57 9         13 $self->{_cur} += $self->{step};
58 9         21 return $res;
59             } else {
60 30 100       58 return if $self->{_ended};
61 27 100       43 $self->{_ended}++ if $self->{_cur} ge $self->{end};
62 27         70 return $self->{_cur}++;
63             }
64             }
65              
66             sub FETCH {
67 43     43   165 my $self = shift;
68 43         61 $self->_next;
69             }
70              
71             1;
72             # ABSTRACT: Generate a tied-scalar iterator for range
73              
74             __END__