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   628 use v5.14;
  50         165  
2 50     50   273 use warnings;
  50         101  
  50         2093  
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.032
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   268 use Type::Tiny::Role;
  50         102  
  50         281  
57 50     50   15310 use Scalar::Util qw(blessed);
  50         109  
  50         1615  
58 50     50   291 use Types::Standard qw(CodeRef ArrayRef);
  50         114  
  50         2813  
59 50     50   342 use Role::Tiny ();
  50         118  
  50         385  
60 50     50   29199 use namespace::clean;
  50         124  
  50         844  
61 50     50   243
  50         98  
  50         367  
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 38258 if (scalar(@$buffer)) {
76 1680         2959 return shift(@$buffer);
77 1680 100       2874 }
78 1         6 my @items = $self->generator->();
79             my $item = shift(@items);
80 1679         3663 return unless defined($item);
81 1679         3986 if (scalar(@items)) {
82 1679 100       3686 push(@$buffer, @items);
83 1220 100       2090 }
84 2         4 my $role = $self->item_type;
85             if (Role::Tiny->is_role($role)) {
86 1220         2509 unless (blessed($item) and $item->does($role)) {
87 1220 100       2989 die "CodeIterator item is not a $role: $item";
88 1086 100 100     9272 }
89 2         47 }
90             return $item;
91             }
92 1218         16843 }
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