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
16 intentional 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
34 mechanism, "WRITING YOUR OWN DERIVED CLASS". (Don't worry, it's a
35 piece of cake)
36
38 There are several classes derived from "IO::Capture".
39
40 IO::Capture::Stdout
41 Module to capture "STDOUT" from program. See IO::Capture::Stdout.
42
43 IO::Capture::Stderr
44 Module to capture "STDERR" from program. See IO::Capture::Stderr.
45
46 IO::Capture::ErrorMessages
47 This method has been depreciated. The only difference between this one
48 and Stderr.pm was the trap for WARN. I found it was fixed in 5.8 so
49 just check in Stderr now. I.e., Just use Stderr now. It (Stderr) will
50 detect what version of perl you are using, and act accordingly. The
51 two ("IO::Capture::ErrorMessages" and "IO::Capture::Stderr") are
52 currently identical, and "IO::Capture::ErrorMessages" will be removed
53 in a future release.
54
55 If you would like to add features to any of these, or build your own
56 module using "IO::Capture" as a base, read on.
57
59 If one of these modules takes care of your problem, install it and have
60 fun!
61
62 But let's say you would like to add a feature to one of the derived
63 classes, say IO::Capture::Stdout. No need to re-write the whole
64 module, just use it as the base, and write your one feature. Here is a
65 somewhat simplified example.
66
67 #
68 # Example module to add a grep_it method
69 #
70 # Give your package a name
71 package MyPackage;
72
73 #use IO:Capture:Stdout as the base
74 use base 'IO::Capture::Stdout';
75
76 #define your method
77 sub grep_it {
78 my $self = shift;
79 my $string = shift;
80 my @found_lines;
81
82 # Making a ref to the array makes it easier to read :-)
83 my $arrayref = \@{$self->{'IO::Capture::messages'}};
84
85 for my $line (@$arrayref) {
86 push @found_lines, $line if $line =~ /$string/;
87 }
88 return wantarray ? @found_lines : scalar(@found_lines);
89 }
90 1;
91
92 Using it in this script
93
94 #!/usr/sbin/perl
95 use strict;
96 use warnings;
97 use MyPackage;
98
99 my $capture = MyPackage->new();
100 $capture->start;
101 print "The quick brown fox jumped over ...";
102 print "garden wall";
103 print "The quick red fox jumped over ...";
104 print "garden wall";
105 $capture->stop;
106 for my $line ($capture->grep_it("fox")) {
107 print "$line\n";
108 }
109
110 Results in
111
112 $ grep_it
113 The quick brown fox jumped over ...
114 The quick red fox jumped over ...
115
117 Before starting your own sub-class, be sure to read through
118 IO::Capture. Pay special attention to the internal methods that are
119 only defined as abstract methods in "IO::Capture". For examples, look
120 at the sub-classes included with this distribution.
121 ("IO::Capture::Stdout", "IO:Capture::Stderr". You can start by copying
122 one of these and using it as a template. They have the required
123 private methods defined already, and you may very well be able to use
124 them as is. Change any methods, and add any new ones, as needed.
125
126 For example, here is a commented copy of "IO::Capture::Stderr".
127
128 #
129 # Example module using abstract class IO::Capture
130 #
131 # Change this to give your class it's own name
132 package IO::Capture::Stderr;
133
134 # Make IO::Capture the base class
135 use base qw/IO::Capture/;
136
137 # If using included utility module in '_start()'
138 use IO::Capture::Tie_STDx;
139
140 # Override the three abstract methods needed to make a valid
141 # module. See IO::Capture manpage
142 # 1) _start - Starts the data capture. Is run from public method
143 # start();
144 #
145 # 2) _retrieve_captured_text() - Move the captured text into the
146 # object hash key, "IO::Capture::messages". Called by public method
147 #
148 # 3) _stop - Stop the data capture. Called by public method 'stop()'
149 # after private method '_retrieve_captured_text()' returns.
150 #
151 sub _start {
152 tie *STDERR, "IO::Capture::Tie_STDx";
153 }
154
155 sub _retrieve_captured_text {
156 my $self = shift;
157 # making a reference to it makes it more readable ;-)
158 my $messages = \@{$self->{'IO::Capture::messages'}};
159
160 @$messages = <STDERR>;
161 }
162
163 sub _stop {
164 untie *STDERR;
165 return 1;
166 }
167 1;
168
169 Lets say you don't want to capture all the text. You just want to grab
170 the lines that have the word "Error" in them. The only thing you need
171 to change is _retrieve_captured_text. (Besides the package name)
172
173 Something like:
174
175 sub _retrieve_captured_text {
176 my $self = shift;
177 # making a reference to it makes it more readable ;-)
178 my $messages = \@{$self->{'IO::Capture::messages'}};
179
180 while (<STDERR>) {
181 push @$messages, $_ if /error/i;
182 }
183 }
184
185 Yes. You could do this easier by just using "IO::Capture::Stderr" as
186 the base and overriding "_retrieve_captured_text" like in "ADDING
187 FEATURES", but hey, we needed an easy example. :-)
188
189 If you want your class to have arguments that users can pass in, just
190 use the default "new()" method and have the arguments passed in as an
191 anonymous array. See the "IO::Capture::Stderr" module for an example.
192
194 Please report bugs on http://rt.cpan.org/
195
197 Special thanks to James E Keenan for many bug fixes and tests he
198 provided.
199
201 Mark Reynolds reynolds<at>sgi.com
202
203 Note: "Change <at" to 'at' sign.>
204
206 Copyright (c) 2003-2005, Mark Reynolds. All Rights Reserved. This
207 module is free software. It may be used, redistributed and/or modified
208 under the same terms as Perl itself.
209
210
211
212perl v5.30.1 2020-01-30 IO::Capture::Overview(3)