1package TAP::Parser::Iterator; 2 3use strict; 4use warnings; 5 6use base 'TAP::Object'; 7 8=head1 NAME 9 10TAP::Parser::Iterator - Base class for TAP source iterators 11 12=head1 VERSION 13 14Version 3.42 15 16=cut 17 18our $VERSION = '3.42'; 19 20=head1 SYNOPSIS 21 22 # to subclass: 23 use TAP::Parser::Iterator (); 24 use base 'TAP::Parser::Iterator'; 25 sub _initialize { 26 # see TAP::Object... 27 } 28 29 sub next_raw { ... } 30 sub wait { ... } 31 sub exit { ... } 32 33=head1 DESCRIPTION 34 35This is a simple iterator base class that defines L<TAP::Parser>'s iterator 36API. Iterators are typically created from L<TAP::Parser::SourceHandler>s. 37 38=head1 METHODS 39 40=head2 Class Methods 41 42=head3 C<new> 43 44Create an iterator. Provided by L<TAP::Object>. 45 46=head2 Instance Methods 47 48=head3 C<next> 49 50 while ( my $item = $iter->next ) { ... } 51 52Iterate through it, of course. 53 54=head3 C<next_raw> 55 56B<Note:> this method is abstract and should be overridden. 57 58 while ( my $item = $iter->next_raw ) { ... } 59 60Iterate raw input without applying any fixes for quirky input syntax. 61 62=cut 63 64sub next { 65 my $self = shift; 66 my $line = $self->next_raw; 67 68 # vms nit: When encountering 'not ok', vms often has the 'not' on a line 69 # by itself: 70 # not 71 # ok 1 - 'I hate VMS' 72 if ( defined($line) and $line =~ /^\s*not\s*$/ ) { 73 $line .= ( $self->next_raw || '' ); 74 } 75 76 return $line; 77} 78 79sub next_raw { 80 require Carp; 81 my $msg = Carp::longmess('abstract method called directly!'); 82 $_[0]->_croak($msg); 83} 84 85=head3 C<handle_unicode> 86 87If necessary switch the input stream to handle unicode. This only has 88any effect for I/O handle based streams. 89 90The default implementation does nothing. 91 92=cut 93 94sub handle_unicode { } 95 96=head3 C<get_select_handles> 97 98Return a list of filehandles that may be used upstream in a select() 99call to signal that this Iterator is ready. Iterators that are not 100handle-based should return an empty list. 101 102The default implementation does nothing. 103 104=cut 105 106sub get_select_handles { 107 return; 108} 109 110=head3 C<wait> 111 112B<Note:> this method is abstract and should be overridden. 113 114 my $wait_status = $iter->wait; 115 116Return the C<wait> status for this iterator. 117 118=head3 C<exit> 119 120B<Note:> this method is abstract and should be overridden. 121 122 my $wait_status = $iter->exit; 123 124Return the C<exit> status for this iterator. 125 126=cut 127 128sub wait { 129 require Carp; 130 my $msg = Carp::longmess('abstract method called directly!'); 131 $_[0]->_croak($msg); 132} 133 134sub exit { 135 require Carp; 136 my $msg = Carp::longmess('abstract method called directly!'); 137 $_[0]->_croak($msg); 138} 139 1401; 141 142=head1 SUBCLASSING 143 144Please see L<TAP::Parser/SUBCLASSING> for a subclassing overview. 145 146You must override the abstract methods as noted above. 147 148=head2 Example 149 150L<TAP::Parser::Iterator::Array> is probably the easiest example to follow. 151There's not much point repeating it here. 152 153=head1 SEE ALSO 154 155L<TAP::Object>, 156L<TAP::Parser>, 157L<TAP::Parser::Iterator::Array>, 158L<TAP::Parser::Iterator::Stream>, 159L<TAP::Parser::Iterator::Process>, 160 161=cut 162 163