File Coverage

blib/lib/Attean/CodeIterator.pm
Criterion Covered Total %
statement 37 37 100.0
branch 10 10 100.0
condition 3 3 100.0
subroutine 9 9 100.0
pod 1 1 100.0
total 60 60 100.0


line stmt bran cond sub pod time code
1 50     50   670 use v5.14;
  50         169  
2 50     50   262 use warnings;
  50         111  
  50         2139  
3              
4             =head1 NAME
5              
6             Attean::CodeIterator - Iterator implementation backed by a generator function
7              
8             =head1 VERSION
9              
10             This document describes Attean::CodeIterator version 0.033
11              
12             =head1 SYNOPSIS
13              
14             use v5.14;
15             use Attean;
16             my $iter = Attean::CodeIterator->new(
17             generator => sub {
18             state $value = 0;
19             Attean::Literal->new(++$value)
20             },
21             item_type => 'Attean::API::Term',
22             );
23            
24             say $iter->next->value; # 1
25             say $iter->next->value; # 2
26             say $iter->next->value; # 3
27              
28             =head1 DESCRIPTION
29              
30             The Attean::CodeIterator class represents a typed iterator.
31             It conforms to the L<Attean::API::Iterator> role.
32              
33             The Attean::CodeIterator constructor requires two named arguments:
34              
35             =over 4
36              
37             =item generator
38              
39             A code reference that when called will return either the iterator's next item,
40             or undef upon reaching the end of iteration.
41              
42             =item item_type
43              
44             A L<Type::Tiny> object representing the type of the items
45             that will be returned from the iterator.
46              
47             =back
48              
49             =head1 METHODS
50              
51             =over 4
52              
53             =cut
54              
55             use Moo;
56 50     50   258 use Type::Tiny::Role;
  50         106  
  50         297  
57 50     50   15129 use Scalar::Util qw(blessed);
  50         148  
  50         1622  
58 50     50   283 use Types::Standard qw(CodeRef ArrayRef);
  50         99  
  50         2988  
59 50     50   336 use Role::Tiny ();
  50         104  
  50         445  
60 50     50   29243 use namespace::clean;
  50         101  
  50         1019  
61 50     50   237
  50         94  
  50         373  
62             with 'Attean::API::Iterator';
63            
64             has generator => (is => 'ro', isa => CodeRef, required => 1);
65             has _buffer => (is => 'ro', isa => ArrayRef, init_arg => undef, default => sub { [] });
66              
67             =item C<< next >>
68              
69             Returns the iterator's next item, or undef upon reaching the end of iteration.
70              
71             =cut
72              
73             my $self = shift;
74             my $buffer = $self->_buffer;
75 1680     1680 1 37639 if (scalar(@$buffer)) {
76 1680         3259 return shift(@$buffer);
77 1680 100       2798 }
78 1         5 my @items = $self->generator->();
79             my $item = shift(@items);
80 1679         3713 return unless defined($item);
81 1679         3808 if (scalar(@items)) {
82 1679 100       3751 push(@$buffer, @items);
83 1220 100       2038 }
84 2         3 my $role = $self->item_type;
85             if (Role::Tiny->is_role($role)) {
86 1220         2558 unless (blessed($item) and $item->does($role)) {
87 1220 100       2969 die "CodeIterator item is not a $role: $item";
88 1086 100 100     9345 }
89 2         44 }
90             return $item;
91             }
92 1218         16616 }
93              
94             1;
95              
96              
97             =back
98              
99             =head1 BUGS
100              
101             Please report any bugs or feature requests to through the GitHub web interface
102             at L<https://github.com/kasei/attean/issues>.
103              
104             =head1 SEE ALSO
105              
106              
107              
108             =head1 AUTHOR
109              
110             Gregory Todd Williams C<< <gwilliams@cpan.org> >>
111              
112             =head1 COPYRIGHT
113              
114             Copyright (c) 2014--2022 Gregory Todd Williams.
115             This program is free software; you can redistribute it and/or modify it under
116             the same terms as Perl itself.
117              
118             =cut