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