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