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   676 use v5.14;
  50         167  
2 50     50   279 use warnings;
  50         109  
  50         2147  
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   281 use Type::Tiny::Role;
  50         97  
  50         280  
57 50     50   15606 use Scalar::Util qw(blessed);
  50         196  
  50         1748  
58 50     50   301 use Types::Standard qw(CodeRef ArrayRef);
  50         107  
  50         2485  
59 50     50   286 use Role::Tiny ();
  50         112  
  50         459  
60 50     50   29764 use namespace::clean;
  50         116  
  50         916  
61 50     50   264
  50         103  
  50         421  
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 45153 if (scalar(@$buffer)) {
76 1680         2439 return shift(@$buffer);
77 1680 100       2832 }
78 1         5 my @items = $self->generator->();
79             my $item = shift(@items);
80 1679         3609 return unless defined($item);
81 1679         3654 if (scalar(@items)) {
82 1679 100       3625 push(@$buffer, @items);
83 1220 100       2546 }
84 2         4 my $role = $self->item_type;
85             if (Role::Tiny->is_role($role)) {
86 1220         2536 unless (blessed($item) and $item->does($role)) {
87 1220 100       2932 die "CodeIterator item is not a $role: $item";
88 1086 100 100     9362 }
89 2         46 }
90             return $item;
91             }
92 1218         17255 }
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