line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package IO::NestedCapture; |
2
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
260707
|
use strict; |
|
6
|
|
|
|
|
18
|
|
|
6
|
|
|
|
|
230
|
|
4
|
6
|
|
|
6
|
|
31
|
use warnings; |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
676
|
|
5
|
|
|
|
|
|
|
|
6
|
6
|
|
|
6
|
|
35
|
use Carp; |
|
6
|
|
|
|
|
15
|
|
|
6
|
|
|
|
|
686
|
|
7
|
6
|
|
|
6
|
|
27709
|
use File::Temp; |
|
6
|
|
|
|
|
265393
|
|
|
6
|
|
|
|
|
1416
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
require Exporter; |
10
|
|
|
|
|
|
|
our @ISA = qw/ Exporter /; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our @EXPORT_OK = qw/ |
13
|
|
|
|
|
|
|
CAPTURE_NONE |
14
|
|
|
|
|
|
|
CAPTURE_STDIN |
15
|
|
|
|
|
|
|
CAPTURE_STDOUT |
16
|
|
|
|
|
|
|
CAPTURE_IN_OUT |
17
|
|
|
|
|
|
|
CAPTURE_STDERR |
18
|
|
|
|
|
|
|
CAPTURE_IN_ERR |
19
|
|
|
|
|
|
|
CAPTURE_OUT_ERR |
20
|
|
|
|
|
|
|
CAPTURE_ALL |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
capture_in |
23
|
|
|
|
|
|
|
capture_out |
24
|
|
|
|
|
|
|
capture_err |
25
|
|
|
|
|
|
|
capture_in_out |
26
|
|
|
|
|
|
|
capture_out_err |
27
|
|
|
|
|
|
|
capture_in_err |
28
|
|
|
|
|
|
|
capture_all |
29
|
|
|
|
|
|
|
/; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( |
32
|
|
|
|
|
|
|
'constants' => [ qw/ |
33
|
|
|
|
|
|
|
CAPTURE_NONE |
34
|
|
|
|
|
|
|
CAPTURE_STDIN |
35
|
|
|
|
|
|
|
CAPTURE_STDOUT |
36
|
|
|
|
|
|
|
CAPTURE_IN_OUT |
37
|
|
|
|
|
|
|
CAPTURE_STDERR |
38
|
|
|
|
|
|
|
CAPTURE_IN_ERR |
39
|
|
|
|
|
|
|
CAPTURE_OUT_ERR |
40
|
|
|
|
|
|
|
CAPTURE_ALL |
41
|
|
|
|
|
|
|
/ ], |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
'subroutines' => [ qw/ |
44
|
|
|
|
|
|
|
capture_in |
45
|
|
|
|
|
|
|
capture_out |
46
|
|
|
|
|
|
|
capture_err |
47
|
|
|
|
|
|
|
capture_in_out |
48
|
|
|
|
|
|
|
capture_out_err |
49
|
|
|
|
|
|
|
capture_in_err |
50
|
|
|
|
|
|
|
capture_all |
51
|
|
|
|
|
|
|
/ ], |
52
|
|
|
|
|
|
|
); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
our $VERSION = '1.03'; |
55
|
|
|
|
|
|
|
|
56
|
6
|
|
|
6
|
|
62
|
use constant CAPTURE_NONE => 0; |
|
6
|
|
|
|
|
19
|
|
|
6
|
|
|
|
|
391
|
|
57
|
6
|
|
|
6
|
|
33
|
use constant CAPTURE_STDIN => 1; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
244
|
|
58
|
6
|
|
|
6
|
|
34
|
use constant CAPTURE_STDOUT => 2; |
|
6
|
|
|
|
|
14
|
|
|
6
|
|
|
|
|
245
|
|
59
|
6
|
|
|
6
|
|
38
|
use constant CAPTURE_IN_OUT => 3; |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
263
|
|
60
|
6
|
|
|
6
|
|
32
|
use constant CAPTURE_STDERR => 4; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
236
|
|
61
|
6
|
|
|
6
|
|
83
|
use constant CAPTURE_IN_ERR => 5; |
|
6
|
|
|
|
|
14
|
|
|
6
|
|
|
|
|
262
|
|
62
|
6
|
|
|
6
|
|
28
|
use constant CAPTURE_OUT_ERR => 6; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
301
|
|
63
|
6
|
|
|
6
|
|
30
|
use constant CAPTURE_ALL => 7; |
|
6
|
|
|
|
|
8
|
|
|
6
|
|
|
|
|
7529
|
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=head1 NAME |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
IO::NestedCapture - module for performing nested STD* handle captures |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=head1 SYNOPSIS |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
use IO::NestedCapture qw/ :subroutines /; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
my $in = IO::NestedCapture->get_next_in; |
74
|
|
|
|
|
|
|
print $in "Harry\n"; |
75
|
|
|
|
|
|
|
print $in "Ron\n"; |
76
|
|
|
|
|
|
|
print $in "Hermione\n"; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
capture_in_out { |
79
|
|
|
|
|
|
|
my @profs = qw( Dumbledore Flitwick McGonagall ); |
80
|
|
|
|
|
|
|
while () { |
81
|
|
|
|
|
|
|
my $prof = shift @prof; |
82
|
|
|
|
|
|
|
print STDOUT "$_ favors $prof"; |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
}; |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my $out = IO::NestedCapture->get_last_out; |
87
|
|
|
|
|
|
|
while (<$out>) { |
88
|
|
|
|
|
|
|
print; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# This program will output: |
92
|
|
|
|
|
|
|
# Harry favors Dumbledore |
93
|
|
|
|
|
|
|
# Ron favors Flitwick |
94
|
|
|
|
|
|
|
# Hermione favors McGonagall |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head1 DESCRIPTION |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
This module was partially inspired by L, but is intended for a very different purpose and is not otherwise related to that package. In particular, I have a need for some pretty aggressive output/input redirection in a web project I'm working on. I'd like to be able to pipe input into a subroutine and then capture that subroutines output to be used as input on the next. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
I was using a fairly clumsy, fragile, and brute force method for doing this. If you're interested, you can take a look at the code on PerlMonks.org: |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
http://perlmonks.org/?node_id=459275 |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
This module implements a much saner approach that involves only a single tie per file handle (regardless of what you want to tie it to). It works by tying the STDIN, STDOUT, and STDERR file handles. Then, uses internal tied class logic to handle any nested use or other work. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
With this module you can capture any combination of STDIN, STDOUT, and STDERR. In the case of STDIN, you may feed any input into capture you want (or even set it to use another file handle). For STDOUT and STDERR you may review the full output of these or prior to capture set a file handle that will receive all the data during the capture. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
As of version 1.02 of this library, there are two different interfaces to the library. The object-oriented version was first, but the new subroutine interface is a little less verbose and a little safer. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=head2 OBJECT-ORIENTED INTERFACE |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
The object-oriented interface is available either through the C class directly or through a single instance of the class available through the C method. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
my $capture = IO::NestedCapture->instance; |
115
|
|
|
|
|
|
|
$capture->start(CAPTURE_STDOUT); |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# Is the same as... |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
IO::NestedCapture->start(CAPTURE_STDOUT); |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
It doesn't really make much difference. |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
You will probably want to important one, several, or all of the capture constants to use this interface. |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head2 SUBROUTINE INTERFACE |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
This interface is available via the import of one of the capture subroutines (or not if you want to fully qualify the names): |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
use IO::NestedCapture 'capture_out'; |
130
|
|
|
|
|
|
|
capture_out { |
131
|
|
|
|
|
|
|
# your code to print to STDOUT here... |
132
|
|
|
|
|
|
|
}; |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
# Is similar to... |
135
|
|
|
|
|
|
|
IO::NestedCapture::capture_err { |
136
|
|
|
|
|
|
|
# your code to print to STDERR here... |
137
|
|
|
|
|
|
|
}; |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
This interface has the advantage of being a little more concise and automatically starts and stops the capture before and after running the code block. This will help avoid typos and other mistakes in your code, such as forgetting to call C when you are done. |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head2 NESTED CAPTURE SUBROUTINES |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
These subroutines are used with the subroutine interface. (See L"SUBROUTINE INTERFACE">.) These subroutines actually use the object-oriented interface internally, so they merely provide a convenient set of shortcuts to it that may help save you some trouble. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
For each subroutine, the subroutine captures one or more file handles before running the given code block and uncaptures them after. In case of an exception, the file handles will still be uncaptured properly. Make sure to put a semi-colon after each method call. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
To manipulate the input, output, and error handles before or after the capture, you will still need to use parts of the object-oriented interface. |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
You will want to import the subroutines you want to use when you load the C object: |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
use IO::NestedCapture qw/ capture_in capture_out /; |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
or you can import all of the capture subroutines with the C<:subroutines> mnemonic: |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
use IO::NestedCapture ':subroutines'; |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
In place of a block, you may also give a code reference as the argument to any of these calls: |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub foo { print "bah\n" } |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
capture_all \&foo; |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
This will run the subroutine foo (with no arguments) and capture the streams it reads/writes. Also, each of the capture subroutines return the return value of the block or rethrow the exceptions raised in the block after stopping the capture. |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=over |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=item capture_in { }; |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
This subroutine captures C for the duration of the given block. |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=cut |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub capture_in(&) { |
174
|
1
|
|
|
1
|
1
|
551
|
my $self = IO::NestedCapture->instance; |
175
|
1
|
|
|
|
|
2
|
my $code = shift; |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# capture input and then turn off capture, even on error |
178
|
1
|
|
|
|
|
4
|
$self->start(CAPTURE_STDIN); |
179
|
1
|
|
|
|
|
2
|
my $result = eval { |
180
|
1
|
|
|
|
|
3
|
$code->(); |
181
|
|
|
|
|
|
|
}; |
182
|
1
|
|
|
|
|
6
|
my $ERROR = $@; |
183
|
1
|
|
|
|
|
3
|
$self->stop(CAPTURE_STDIN); |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# rethrow any errors or return normally |
186
|
1
|
50
|
|
|
|
5
|
die $ERROR if $ERROR; |
187
|
0
|
|
|
|
|
0
|
return $result; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=item capture_out { }; |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
This subroutine captures C for the duration of the given block. |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=cut |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub capture_out(&) { |
197
|
1
|
|
|
1
|
1
|
903
|
my $self = IO::NestedCapture->instance; |
198
|
1
|
|
|
|
|
1
|
my $code = shift; |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
# capture output and then turn off capture, even on error |
201
|
1
|
|
|
|
|
12
|
$self->start(CAPTURE_STDOUT); |
202
|
1
|
|
|
|
|
2
|
my $result = eval { |
203
|
1
|
|
|
|
|
3
|
$code->(); |
204
|
|
|
|
|
|
|
}; |
205
|
1
|
|
|
|
|
7
|
my $ERROR = $@; |
206
|
1
|
|
|
|
|
4
|
$self->stop(CAPTURE_STDOUT); |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# rethrow any errors or return normally |
209
|
1
|
50
|
|
|
|
8
|
die $ERROR if $ERROR; |
210
|
0
|
|
|
|
|
0
|
return $result; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=item capture_err { }; |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
This subroutine captures C for the duration of the given block. |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=cut |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
sub capture_err(&) { |
220
|
1
|
|
|
1
|
1
|
965
|
my $self = IO::NestedCapture->instance; |
221
|
1
|
|
|
|
|
2
|
my $code = shift; |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
# capture error output and then turn off capture, even on error |
224
|
1
|
|
|
|
|
3
|
$self->start(CAPTURE_STDERR); |
225
|
1
|
|
|
|
|
2
|
my $result = eval { |
226
|
1
|
|
|
|
|
3
|
$code->(); |
227
|
|
|
|
|
|
|
}; |
228
|
1
|
|
|
|
|
6
|
my $ERROR = $@; |
229
|
1
|
|
|
|
|
2
|
$self->stop(CAPTURE_STDERR); |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# rethrow any errors or return normally |
232
|
1
|
50
|
|
|
|
5
|
die $ERROR if $ERROR; |
233
|
0
|
|
|
|
|
0
|
return $result; |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=item capture_in_out { }; |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
This subroutine captures C and C for the duration of the given block. |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
=cut |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
sub capture_in_out(&) { |
243
|
1
|
|
|
1
|
1
|
1113
|
my $self = IO::NestedCapture->instance; |
244
|
1
|
|
|
|
|
2
|
my $code = shift; |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# capture input and output and then turn off capture, even on error |
247
|
1
|
|
|
|
|
3
|
$self->start(CAPTURE_IN_OUT); |
248
|
1
|
|
|
|
|
2
|
my $result = eval { |
249
|
1
|
|
|
|
|
4
|
$code->(); |
250
|
|
|
|
|
|
|
}; |
251
|
1
|
|
|
|
|
8
|
my $ERROR = $@; |
252
|
1
|
|
|
|
|
4
|
$self->stop(CAPTURE_IN_OUT); |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# rethrow any errors or return normally |
255
|
1
|
50
|
|
|
|
7
|
die $ERROR if $ERROR; |
256
|
0
|
|
|
|
|
0
|
return $result; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=item capture_in_err { }; |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
This subroutine captures C and C for the duration of the given block. |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=cut |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
sub capture_in_err(&) { |
266
|
1
|
|
|
1
|
1
|
1503
|
my $self = IO::NestedCapture->instance; |
267
|
1
|
|
|
|
|
3
|
my $code = shift; |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
# capture input and error output and then turn off capture, even on error |
270
|
1
|
|
|
|
|
4
|
$self->start(CAPTURE_IN_ERR); |
271
|
1
|
|
|
|
|
3
|
my $result = eval { |
272
|
1
|
|
|
|
|
4
|
$code->(); |
273
|
|
|
|
|
|
|
}; |
274
|
1
|
|
|
|
|
8
|
my $ERROR = $@; |
275
|
1
|
|
|
|
|
3
|
$self->stop(CAPTURE_IN_ERR); |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
# rethrow any errors or return normally |
278
|
1
|
50
|
|
|
|
7
|
die $ERROR if $ERROR; |
279
|
0
|
|
|
|
|
0
|
return $result; |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=item capture_out_err { }; |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
This subroutine captures C and C for the duration of the given block. |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=cut |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
sub capture_out_err(&) { |
289
|
1
|
|
|
1
|
1
|
1604
|
my $self = IO::NestedCapture->instance; |
290
|
1
|
|
|
|
|
2
|
my $code = shift; |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
# capture output and error output and then turn off capture, even on error |
293
|
1
|
|
|
|
|
4
|
$self->start(CAPTURE_OUT_ERR); |
294
|
1
|
|
|
|
|
2
|
my $result = eval { |
295
|
1
|
|
|
|
|
4
|
$code->(); |
296
|
|
|
|
|
|
|
}; |
297
|
1
|
|
|
|
|
9
|
my $ERROR = $@; |
298
|
1
|
|
|
|
|
5
|
$self->stop(CAPTURE_OUT_ERR); |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
# rethrow any errors or return normally |
301
|
1
|
50
|
|
|
|
13
|
die $ERROR if $ERROR; |
302
|
0
|
|
|
|
|
0
|
return $result; |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=item capture_all { }; |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
This subroutine captures C, C, and C for the duration of the given block. |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=cut |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub capture_all(&) { |
312
|
1
|
|
|
1
|
1
|
1659
|
my $self = IO::NestedCapture->instance; |
313
|
1
|
|
|
|
|
2
|
my $code = shift; |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# capture input, output and error output and then turn off capture, even on |
316
|
|
|
|
|
|
|
# error |
317
|
1
|
|
|
|
|
10
|
$self->start(CAPTURE_ALL); |
318
|
1
|
|
|
|
|
2
|
my $result = eval { |
319
|
1
|
|
|
|
|
5
|
$code->(); |
320
|
|
|
|
|
|
|
}; |
321
|
1
|
|
|
|
|
7
|
my $ERROR = $@; |
322
|
1
|
|
|
|
|
4
|
$self->stop(CAPTURE_ALL); |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
# rethrow any errors or return normally |
325
|
1
|
50
|
|
|
|
6
|
die $ERROR if $ERROR; |
326
|
0
|
|
|
|
|
0
|
return $result; |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=back |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=head2 NESTED CAPTURE CONSTANTS |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
These constants are used with the object-oriented interface. (See L"OBJECT-ORIENTED INTERFACE">.) |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
You will want to import the constants you want when you load the C module: |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
use IO::NestedCapture qw/ CAPTURE_STDIN CAPTURE_STDOUT /; |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
or you may import all of them with the C<:constants> mnemonic.: |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
use IO::NestedCapture ':constants'; |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=over |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=item CAPTURE_STDIN |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Used to start or stop capture on STDIN. |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=item CAPTURE_STDOUT |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
Used to start or stop capture on STDOUT. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=item CAPTURE_STDERR |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
Used to start or stop capture on STDERR. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=item CAPTURE_IN_OUT |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
Used to start or stop capture on STDIN and STDOUT. This is a shortcut for "C". |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=item CAPTURE_IN_ERR |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
Used to start or stop cpature on STDIN and STDERR. This is a shortcut for "C". |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=item CAPTURE_OUT_ERR |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
Used to start or stop capture on STDOUT and STDERR. This is a shortcut for "C".) |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=item CAPTURE_ALL |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
Used to start or stop capture on STDIN, STDOUT, and STDERR. This is a shortcut for "C". |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=back |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=head2 OBJECT-ORIENTED CAPTURE METHODS |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
These are the methods used for the object-oriented interface. (See L"OBJECT-ORIENTED INTERFACE">.) |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=over |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=item $capture = IO::NestedCapture-Einstance; |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
Retrieves an instance of the singleton. Use of this method is optional. |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=cut |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
my $instance; |
388
|
|
|
|
|
|
|
sub instance { |
389
|
|
|
|
|
|
|
# We've already got one... |
390
|
117
|
100
|
|
117
|
1
|
1664
|
return $instance if $instance; |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
# I told 'im we already got one... |
393
|
5
|
|
|
|
|
14
|
my $class = shift; |
394
|
5
|
|
|
|
|
26
|
return $instance = bless {}, $class; |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
=item IO::NestedCapture-Estart($capture_what) |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=item $capture-Estart($capture_what) |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
The C<$capture_what> variable is a bit field that should be set to one or more of the L"NESTED CAPTURE CONSTANTS"> bit-or'd together. Until this method is called, the STD* handles are not tied to the C interface. The tie will only occur on the very first call to this method. After that, the nesting is handled with stacks internal to the C singleton. |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
If you're capturing STDIN, you should be sure to fill in the input using the C method first if you want there to be any to be read. |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
If you're capturing STDOUT or STDERR, you should be sure to set the file handles to output too, if you want to do that before calling this method. |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
=cut |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
my %fhs = ( |
410
|
|
|
|
|
|
|
CAPTURE_STDIN() => 'STDIN', |
411
|
|
|
|
|
|
|
CAPTURE_STDOUT() => 'STDOUT', |
412
|
|
|
|
|
|
|
CAPTURE_STDERR() => 'STDERR', |
413
|
|
|
|
|
|
|
); |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
sub start { |
416
|
28
|
|
|
28
|
1
|
8957
|
my $self = shift->instance; |
417
|
28
|
|
|
|
|
57
|
my $capture_what = shift; |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
# check parameters for sanity |
420
|
28
|
100
|
|
|
|
279
|
$capture_what >= CAPTURE_NONE |
421
|
|
|
|
|
|
|
or croak "start() called without specifying which handles to capture."; |
422
|
27
|
100
|
|
|
|
215
|
$capture_what <= CAPTURE_ALL |
423
|
|
|
|
|
|
|
or croak "start() called with unknown capture parameters."; |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
# For each capture constant asked to start, let's make sure it's tied and |
426
|
|
|
|
|
|
|
# then push us up onto the next level |
427
|
26
|
|
|
|
|
63
|
for my $capcon ((CAPTURE_STDIN, CAPTURE_STDOUT, CAPTURE_STDERR)) { |
428
|
76
|
100
|
|
|
|
317
|
if ($capture_what & $capcon) { |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
# figure out what we're checking |
431
|
35
|
|
|
|
|
76
|
my $fh = $fhs{$capcon}; |
432
|
|
|
|
|
|
|
|
433
|
6
|
|
|
6
|
|
39
|
no strict 'refs'; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
2969
|
|
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
# croak if it's tied to the wrong thingy, tie it if we're untied |
436
|
35
|
100
|
100
|
|
|
295
|
if (tied(*$fh) && !UNIVERSAL::isa(tied(*$fh), 'IO::NestedCapture')) { |
|
|
100
|
|
|
|
|
|
437
|
1
|
|
|
|
|
108
|
croak "start() failed because $fh is not tied as expected."; |
438
|
|
|
|
|
|
|
} elsif (!tied(*$fh)) { |
439
|
27
|
|
|
|
|
135
|
tie *$fh, 'IO::NestedCapture', $fh; |
440
|
|
|
|
|
|
|
} |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
# grab the one being prepped or create it |
443
|
34
|
|
|
|
|
78
|
my $pushed_fh; |
444
|
34
|
|
|
|
|
49
|
my $pushed_reset = 0; |
445
|
34
|
100
|
|
|
|
111
|
if ($pushed_fh = delete $self->{"${fh}_next"}) { |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
# if this is our own file handle, we want to go back to the top |
448
|
|
|
|
|
|
|
# of the file before starting. if this is the user's file |
449
|
|
|
|
|
|
|
# handle, we won't mess with it. |
450
|
9
|
|
|
|
|
29
|
my $next_reset = delete $self->{"${fh}_next_reset"}; |
451
|
9
|
100
|
|
|
|
513
|
seek $pushed_fh, 0, 0 if $next_reset; |
452
|
|
|
|
|
|
|
} else { |
453
|
25
|
|
|
|
|
95
|
$pushed_fh = File::Temp::tempfile; |
454
|
25
|
|
|
|
|
16264
|
$pushed_reset = 1; |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
# put this one on top of the file handle stack |
458
|
34
|
|
|
|
|
57
|
push @{ $self->{"${fh}_current"} }, $pushed_fh; |
|
34
|
|
|
|
|
191
|
|
459
|
34
|
|
|
|
|
54
|
push @{ $self->{"${fh}_current_reset"} }, $pushed_reset; |
|
34
|
|
|
|
|
134
|
|
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=item IO::NestedCapture-Estop($uncapture_what) |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
=item $capture-Estop($uncapture_what) |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
The C<$uncapture_what> variable is a bit field that should be set to one or more of the L"NESTED CAPTURE CONSTANTS"> bit-or'd together. If this method is called and the internal nesting state shows that this is the last layer to remove, the associated STD* handles are untied. If C<$uncapture_what> indicates that a certain handle should be uncaptured, but it isn't currently captured, an error will be thrown. |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=cut |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
sub stop { |
473
|
28
|
|
|
28
|
1
|
29292
|
my $self = shift->instance; |
474
|
28
|
|
|
|
|
55
|
my $uncapture_what = shift; |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
# check parameters for sanity |
477
|
28
|
100
|
|
|
|
285
|
$uncapture_what > 0 |
478
|
|
|
|
|
|
|
or croak "stop() called without specifying which handles to uncapture."; |
479
|
27
|
100
|
|
|
|
254
|
$uncapture_what <= CAPTURE_ALL |
480
|
|
|
|
|
|
|
or croak "stop() called with unknown uncapture parameters."; |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
# For each uncapture constant asked to stop, check to make sure we're |
483
|
|
|
|
|
|
|
# stopping after one or more starts, pop the file handle, and untie if it's |
484
|
|
|
|
|
|
|
# the last one |
485
|
26
|
|
|
|
|
56
|
for my $uncapcon ((CAPTURE_STDIN, CAPTURE_STDOUT, CAPTURE_STDERR)) { |
486
|
74
|
100
|
|
|
|
278
|
if ($uncapture_what & $uncapcon) { |
487
|
|
|
|
|
|
|
# figure out what we're checking |
488
|
36
|
|
|
|
|
72
|
my $fh = $fhs{$uncapcon}; |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
# is this in use or should we croak? |
491
|
36
|
100
|
100
|
|
|
337
|
(defined $self->{"${fh}_current"} && @{ $self->{"${fh}_current"} }) |
|
35
|
|
|
|
|
317
|
|
492
|
|
|
|
|
|
|
or croak "stop() asked to stop $fh, but it wasn't started"; |
493
|
|
|
|
|
|
|
|
494
|
34
|
|
|
|
|
59
|
$self->{"${fh}_last"} = pop @{ $self->{"${fh}_current"} }; |
|
34
|
|
|
|
|
125
|
|
495
|
34
|
|
|
|
|
811
|
seek $self->{"${fh}_last"}, 0, 0 |
496
|
34
|
100
|
|
|
|
654
|
if pop @{ $self->{"${fh}_current_reset"} }; |
497
|
|
|
|
|
|
|
|
498
|
34
|
100
|
|
|
|
128
|
unless (@{ $self->{"${fh}_current"} }) { |
|
34
|
|
|
|
|
121
|
|
499
|
6
|
|
|
6
|
|
49
|
no strict 'refs'; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
5649
|
|
500
|
27
|
|
|
|
|
227
|
untie *$fh; |
501
|
|
|
|
|
|
|
} |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
} |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=item $handle = IO::NestedCapture-Eget_next_in |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=item $handle = $capture-Eget_next_in |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
This method returns the file handle that will be used for STDIN after the next call to C. If one has not been set using C, then a seekable file handle will be created. If you just use the automatically created file handle (which is created using L), then C will seek to the top of the file handle before use. |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=cut |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
sub get_next_in { |
515
|
9
|
|
|
9
|
1
|
2706
|
my $self = shift->instance; |
516
|
|
|
|
|
|
|
|
517
|
9
|
100
|
|
|
|
39
|
unless ($self->{'STDIN_next'}) { |
518
|
8
|
|
|
|
|
43
|
$self->{'STDIN_next'} = File::Temp::tempfile; |
519
|
8
|
|
|
|
|
6363
|
$self->{'STDIN_next_reset'} = 1; |
520
|
|
|
|
|
|
|
} |
521
|
|
|
|
|
|
|
|
522
|
9
|
|
|
|
|
34
|
return $self->{'STDIN_next'}; |
523
|
|
|
|
|
|
|
} |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
=item IO::NestedCapture-Eset_next_in($handle) |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
=item $capture-Ein($handle) |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
The given file handle is used as the file handle to read from after C is called. If you set a file handle yourself, you must make sure that it is ready to be read from when you call C (i.e., the file handle pointer won't be reset to the top of the file automatically). |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
=cut |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
sub set_next_in { |
534
|
1
|
|
|
1
|
1
|
4
|
my $self = shift->instance; |
535
|
1
|
|
|
|
|
10
|
my $handle = shift; |
536
|
|
|
|
|
|
|
|
537
|
1
|
|
|
|
|
3
|
$self->{'STDIN_next'} = $handle; |
538
|
1
|
|
|
|
|
3
|
delete $self->{'STDIN_next_reset'}; |
539
|
|
|
|
|
|
|
|
540
|
1
|
|
|
|
|
2
|
return; |
541
|
|
|
|
|
|
|
} |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
=item $handle = IO::NestedCapture-Eget_last_out |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
=item $handle = $capture-Eget_last_out |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
Retrieve the file handle used to capture the output prior to the previous call to C. If this file handle was automatically generated (i.e., not set with C, then the file pointer will already be set to the top of the file and ready to read). |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
=cut |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
sub get_last_out { |
552
|
9
|
|
|
9
|
1
|
4661
|
my $self = shift->instance; |
553
|
9
|
|
|
|
|
46
|
return $self->{'STDOUT_last'}; |
554
|
|
|
|
|
|
|
} |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
=item IO::NestedCapture-Eset_next_out($handle) |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
=item $capture-Eset_next_out($handle) |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
Install your own file handle to capture the output following the next call to C. Make sure the file handle is in the exact state you want before calling C. |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
=cut |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
sub set_next_out { |
565
|
0
|
|
|
0
|
1
|
0
|
my $self = shift->instance; |
566
|
0
|
|
|
|
|
0
|
my $handle = shift; |
567
|
|
|
|
|
|
|
|
568
|
0
|
|
|
|
|
0
|
$self->{'STDOUT_next'} = $handle; |
569
|
0
|
|
|
|
|
0
|
delete $self->{'STDOUT_next_reset'}; |
570
|
|
|
|
|
|
|
|
571
|
0
|
|
|
|
|
0
|
return; |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
=item $handle = IO::NestedCapture-Eget_last_error |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
=item $handle = $capture-Eget_last_error |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
Retrieve the file handle used to capture the error output prior to the previous call to C. If this file handle was automatically generated (i.e., not set with C, then the file pointer will already be set to the top of the file and ready to read). |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
=cut |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
sub get_last_err { |
583
|
3
|
|
|
3
|
0
|
23095
|
my $self = shift->instance; |
584
|
3
|
|
|
|
|
13
|
return $self->{'STDERR_last'}; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=item IO::NestedCapture-Eset_next_err($handle) |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=item $capture-Eset_next_err($handle) |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
Install your own file handle to capture the error output following the next call to C. Make sure the file handle is in the exact state you want before calling C. |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
=cut |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
sub set_next_err { |
596
|
0
|
|
|
0
|
1
|
0
|
my $self = shift->instance; |
597
|
0
|
|
|
|
|
0
|
my $handle = shift; |
598
|
|
|
|
|
|
|
|
599
|
0
|
|
|
|
|
0
|
$self->{'STDERR_next'} = $handle; |
600
|
0
|
|
|
|
|
0
|
delete $self->{'STDERR_next_reset'}; |
601
|
|
|
|
|
|
|
|
602
|
0
|
|
|
|
|
0
|
return; |
603
|
|
|
|
|
|
|
} |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
=back |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
=cut |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
# The rest of this is private tie stuff... |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
# Okay, so the documentation lies. This isn't really a singleton, but the extra |
612
|
|
|
|
|
|
|
# objects are internally used as ties only. |
613
|
|
|
|
|
|
|
sub TIEHANDLE { |
614
|
27
|
|
|
27
|
|
45
|
my $class = shift; |
615
|
27
|
|
|
|
|
76
|
my $instance = $class->instance; |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
# Make a non-singleton tie class... shhhhhh. |
618
|
27
|
|
|
|
|
242
|
my $self = bless { |
619
|
|
|
|
|
|
|
instance => $instance, |
620
|
|
|
|
|
|
|
fh => shift, |
621
|
|
|
|
|
|
|
}, $class; |
622
|
|
|
|
|
|
|
} |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
sub WRITE { |
625
|
1
|
|
|
1
|
|
305
|
my $self = shift; |
626
|
1
|
|
|
|
|
3
|
my $buf = shift; |
627
|
1
|
|
|
|
|
3
|
my $len = shift; |
628
|
1
|
|
|
|
|
2
|
my $off = shift; |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
# load state |
631
|
1
|
|
|
|
|
2
|
my $capture = $self->{instance}; |
632
|
1
|
|
|
|
|
2
|
my $fh = $self->{fh}; |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
# write |
635
|
1
|
|
|
|
|
58
|
syswrite $capture->{"${fh}_current"}[-1], $buf, $len, $off; |
636
|
|
|
|
|
|
|
} |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
sub PRINT { |
639
|
33
|
|
|
33
|
|
8377
|
my $self = shift; |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
# load state |
642
|
33
|
|
|
|
|
212
|
my $capture = $self->{instance}; |
643
|
33
|
|
|
|
|
46
|
my $fh = $self->{fh}; |
644
|
33
|
|
|
|
|
85
|
my $handle = $capture->{"${fh}_current"}[-1]; |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
# write |
647
|
33
|
|
|
|
|
305
|
print $handle @_; |
648
|
|
|
|
|
|
|
} |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
sub PRINTF { |
651
|
1
|
|
|
1
|
|
8
|
my $self = shift; |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
# load state |
654
|
1
|
|
|
|
|
3
|
my $capture = $self->{instance}; |
655
|
1
|
|
|
|
|
2
|
my $fh = $self->{fh}; |
656
|
1
|
|
|
|
|
4
|
my $handle = $capture->{"${fh}_current"}[-1]; |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
# write |
659
|
1
|
|
|
|
|
23
|
printf $handle @_; |
660
|
|
|
|
|
|
|
} |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
sub READ { |
663
|
1
|
|
|
1
|
|
538
|
my $self = shift; |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
# load state |
666
|
1
|
|
|
|
|
2
|
my $capture = $self->{instance}; |
667
|
1
|
|
|
|
|
3
|
my $fh = $self->{fh}; |
668
|
1
|
|
|
|
|
4
|
my $handle = $capture->{"${fh}_current"}[-1]; |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
# read |
671
|
1
|
|
|
|
|
13
|
read $handle, $_[0], $_[1], $_[2]; |
672
|
|
|
|
|
|
|
} |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
sub READLINE { |
675
|
39
|
|
|
39
|
|
4524
|
my $self = shift; |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
# load state |
678
|
39
|
|
|
|
|
62
|
my $capture = $self->{instance}; |
679
|
39
|
|
|
|
|
69
|
my $fh = $self->{fh}; |
680
|
39
|
|
|
|
|
97
|
my $handle = $capture->{"${fh}_current"}[-1]; |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
# read |
683
|
39
|
|
|
|
|
481
|
readline $handle; |
684
|
|
|
|
|
|
|
} |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
sub GETC { |
687
|
7
|
|
|
7
|
|
605
|
my $self = shift; |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
# load state |
690
|
7
|
|
|
|
|
12
|
my $capture = $self->{instance}; |
691
|
7
|
|
|
|
|
10
|
my $fh = $self->{fh}; |
692
|
7
|
|
|
|
|
16
|
my $handle = $capture->{"${fh}_current"}[-1]; |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
# read |
695
|
7
|
|
|
|
|
46
|
getc $handle; |
696
|
|
|
|
|
|
|
} |
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
sub CLOSE { |
699
|
1
|
|
|
1
|
|
3
|
my $self = shift; |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
# load state |
702
|
1
|
|
|
|
|
4
|
my $capture = $self->{instance}; |
703
|
1
|
|
|
|
|
3
|
my $fh = $self->{fh}; |
704
|
1
|
|
|
|
|
296
|
my $handle = $capture->{"${fh}_current"}[-1]; |
705
|
|
|
|
|
|
|
|
706
|
|
|
|
|
|
|
# close |
707
|
1
|
|
|
|
|
357
|
close $handle; |
708
|
|
|
|
|
|
|
} |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
=head1 EXPORTS |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
This module exports all of the constants used with the object-oriented interface and the subroutines used with the subroutine interface. |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
See L"NESTED CAPTURE CONSTANTS"> for the specific constant names or use C<:constants> to import all the constants. |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
See L"NESTED CAPTURE SUBROUTINES"> for the specific subroutine names or use C<:subroutines> to import all the subroutines. |
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
=head1 SEE ALSO |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
L |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=head1 AUTHOR |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
Andrew Sterling Hanenkamp, Ehanenkamp@cpan.orgE |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
Copyright 2005 Andrew Sterling Hanenkamp. |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
This code is licensed and distributed under the same terms as Perl itself. |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
=cut |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
1 |