1IO::Capture::Overview(3U)ser Contributed Perl DocumentatiIoOn::Capture::Overview(3)
2
3
4
6 Overview of "IO::Capture" Module, and classes derived from it.
7
9 The modules in this distribution are designed to allow you to capture
10 and process output sent to STDOUT and/or STDERR.
11
12 I initial created the modules to use in building module tests. I
13 wanted to be able to intentionally cause errors, and insure the module
14 responded correctly. E.g., Call a class method without a required
15 argument. Using IO::Capture keeps the user from seeing these inten‐
16 tional errors when running 'make test'.
17
18 I have also found this useful on occasion in Perl Tk apps, where I
19 wanted to capture output from a Perl module I was using. I could then
20 capture, then put the text into a log or message window.
21
22 Note: None of the modules currently distributed will capture from the
23 'system' Perl function, or the like. It could be done, but generally,
24 if you would like to capture from a system command, you don't need this
25 module, just use the backticks operators.
26
27 my $output = '/usr/bin/ls';
28
29 They are small, lightweight modules. Instead of designing in a lot of
30 features, we designed it to be easily reusable and adaptable. A module
31 can be quickly built, that incorporates custom methods, but reuses all
32 existing features of one of the derived classes. See the section on
33 "ADDING FEATURES" Or, if you need to change the actual capture mecha‐
34 nism, "WRITING YOUR OWN DERIVED CLASS". (Don't worry, it's a piece of
35 cake)
36
38 There are several classes derived from "IO::Capture".
39
40 IO::Capture::Stdout
41
42 Module to capture "STDOUT" from program. See IO::Capture::Stdout.
43
44 IO::Capture::Stderr
45
46 Module to capture "STDERR" from program. See IO::Capture::Stderr.
47
48 IO::Capture::ErrorMessages
49
50 This method has been depreciated. The only difference between this one
51 and Stderr.pm was the trap for WARN. I found it was fixed in 5.8 so
52 just check in Stderr now. I.e., Just use Stderr now. It (Stderr) will
53 detect what version of perl you are using, and act accordingly. The
54 two ("IO::Capture::ErrorMessages" and "IO::Capture::Stderr") are cur‐
55 rently identical, and "IO::Capture::ErrorMessages" will be removed in a
56 future release.
57
58 If you would like to add features to any of these, or build your own
59 module using "IO::Capture" as a base, read on.
60
62 If one of these modules takes care of your problem, install it and have
63 fun!
64
65 But let's say you would like to add a feature to one of the derived
66 classes, say IO::Capture::Stdout. No need to re-write the whole mod‐
67 ule, just use it as the base, and write your one feature. Here is a
68 somewhat simplified example.
69
70 #
71 # Example module to add a grep_it method
72 #
73 # Give your package a name
74 package MyPackage;
75
76 #use IO:Capture:Stdout as the base
77 use base 'IO::Capture::Stdout';
78
79 #define your method
80 sub grep_it {
81 my $self = shift;
82 my $string = shift;
83 my @found_lines;
84
85 # Making a ref to the array makes it easier to read :-)
86 my $arrayref = \@{$self->{'IO::Capture::messages'}};
87
88 for my $line (@$arrayref) {
89 push @found_lines, $line if $line =~ /$string/;
90 }
91 return wantarray ? @found_lines : scalar(@found_lines);
92 }
93 1;
94
95 Using it in this script
96
97 #!/usr/sbin/perl
98 use strict;
99 use warnings;
100 use MyPackage;
101
102 my $capture = MyPackage->new();
103 $capture->start;
104 print "The quick brown fox jumped over ...";
105 print "garden wall";
106 print "The quick red fox jumped over ...";
107 print "garden wall";
108 $capture->stop;
109 for my $line ($capture->grep_it("fox")) {
110 print "$line\n";
111 }
112
113 Results in
114
115 $ grep_it
116 The quick brown fox jumped over ...
117 The quick red fox jumped over ...
118
120 Before starting your own sub-class, be sure to read through IO::Cap‐
121 ture. Pay special attention to the internal methods that are only
122 defined as abstract methods in "IO::Capture". For examples, look at
123 the sub-classes included with this distribution. ("IO::Capture::Std‐
124 out", "IO:Capture::Stderr". You can start by copying one of these and
125 using it as a template. They have the required private methods defined
126 already, and you may very well be able to use them as is. Change any
127 methods, and add any new ones, as needed.
128
129 For example, here is a commented copy of "IO::Capture::Stderr".
130
131 #
132 # Example module using abstract class IO::Capture
133 #
134 # Change this to give your class it's own name
135 package IO::Capture::Stderr;
136
137 # Make IO::Capture the base class
138 use base qw/IO::Capture/;
139
140 # If using included utility module in '_start()'
141 use IO::Capture::Tie_STDx;
142
143 # Override the three abstract methods needed to make a valid
144 # module. See IO::Capture manpage
145 # 1) _start - Starts the data capture. Is run from public method
146 # start();
147 #
148 # 2) _retrieve_captured_text() - Move the captured text into the
149 # object hash key, "IO::Capture::messages". Called by public method
150 #
151 # 3) _stop - Stop the data capture. Called by public method 'stop()'
152 # after private method '_retrieve_captured_text()' returns.
153 #
154 sub _start {
155 tie *STDERR, "IO::Capture::Tie_STDx";
156 }
157
158 sub _retrieve_captured_text {
159 my $self = shift;
160 # making a reference to it makes it more readable ;-)
161 my $messages = \@{$self->{'IO::Capture::messages'}};
162
163 @$messages = <STDERR>;
164 }
165
166 sub _stop {
167 untie *STDERR;
168 return 1;
169 }
170 1;
171
172 Lets say you don't want to capture all the text. You just want to grab
173 the lines that have the word "Error" in them. The only thing you need
174 to change is _retrieve_captured_text. (Besides the package name)
175
176 Something like:
177
178 sub _retrieve_captured_text {
179 my $self = shift;
180 # making a reference to it makes it more readable ;-)
181 my $messages = \@{$self->{'IO::Capture::messages'}};
182
183 while (<STDERR>) {
184 push @$messages, $_ if /error/i;
185 }
186 }
187
188 Yes. You could do this easier by just using "IO::Capture::Stderr" as
189 the base and overriding "_retrieve_captured_text" like in "ADDING FEA‐
190 TURES", but hey, we needed an easy example. :-)
191
192 If you want your class to have arguments that users can pass in, just
193 use the default "new()" method and have the arguments passed in as an
194 anonymous array. See the "IO::Capture::Stderr" module for an example.
195
197 Please report bugs on http://rt.cpan.org/
198
200 Special thanks to James E Keenan for many bug fixes and tests he pro‐
201 vided.
202
204 Mark Reynolds reynolds<at>sgi.com
205
206 Note: "Change <at" to 'at' sign.>
207
209 Copyright (c) 2003-2005, Mark Reynolds. All Rights Reserved. This mod‐
210 ule is free software. It may be used, redistributed and/or modified
211 under the same terms as Perl itself.
212
213
214
215perl v5.8.8 2005-04-29 IO::Capture::Overview(3)