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