File Coverage

blib/lib/Range/HandleIter.pm
Criterion Covered Total %
statement 44 44 100.0
branch 19 20 95.0
condition 4 5 80.0
subroutine 8 8 100.0
pod 1 1 100.0
total 76 78 97.4


line stmt bran cond sub pod time code
1             package Range::HandleIter;
2              
3             our $DATE = '2019-05-12'; # DATE
4             our $VERSION = '0.001'; # VERSION
5              
6 1     1   65068 use strict;
  1         10  
  1         29  
7 1     1   5 use warnings;
  1         2  
  1         26  
8              
9 1     1   5 use Exporter qw(import);
  1         2  
  1         121  
10             our @EXPORT_OK = qw(range_handleiter);
11              
12             sub range_handleiter($$;$) {
13 7     7 1 3521 my ($start, $end, $step) = @_;
14              
15 7         29 tie *FH, 'Range::HandleIter::Tie', $start, $end, $step;
16 7         34 \*FH;
17             }
18              
19             package # hide from PAUSE
20             Range::HandleIter::Tie;
21              
22 1     1   7 use Scalar::Util qw(looks_like_number);
  1         2  
  1         360  
23              
24             sub TIEHANDLE {
25 7     7   14 my $class = shift;
26 7         13 my ($start, $end, $step) = @_;
27 7   100     31 $step //= 1;
28              
29 7         31 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     34 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       9 die "Cannot specify step != 1 for non-numeric range" if $step != 1;
45 3 100       11 $self->{_ended}++ if $start gt $end;
46             }
47 7         31 bless $self, $class;
48             }
49              
50             sub _next {
51 43     43   56 my $self = shift;
52              
53 43 100       72 if ($self->{_num}) {
54 13 100       28 $self->{_ended}++ if $self->{_cur} > $self->{end};
55 13 100       27 return if $self->{_ended};
56 9         13 push @{ $self->{_buf} }, $self->{_cur};
  9         26  
57 9         18 $self->{_cur} += $self->{step};
58             } else {
59 30 100       52 return if $self->{_ended};
60 27 100       49 $self->{_ended}++ if $self->{_cur} ge $self->{end};
61 27         35 push @{ $self->{_buf} }, $self->{_cur}++;
  27         60  
62             }
63             }
64              
65             sub READLINE {
66 43     43   162 my $self = shift;
67 43         81 $self->_next;
68 43 100       51 if (@{ $self->{_buf} }) {
  43         76  
69 36         47 $self->{_len}++;
70 36         37 shift @{ $self->{_buf} };
  36         77  
71             } else {
72 7         16 undef;
73             }
74             }
75              
76             1;
77             # ABSTRACT: Generate a tied-handle iterator for range
78              
79             __END__