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