Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
IO::Capture::Overview(User Contributed Perl DocumentatIO::Capture::Overview(3)

       Overview	of "IO::Capture" Module, and classes derived from it.

       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
       "ADDING FEATURES"  Or, if you need to change the	actual capture
       mechanism, "WRITING YOUR	OWN DERIVED CLASS".  (Don't worry, it's	a
       piece of	cake)

       There are several classes derived from "IO::Capture".

       Module to capture "STDOUT" from program.	 See IO::Capture::Stdout.

       Module to capture "STDERR" from program.	 See IO::Capture::Stderr.

       This method has been depreciated.  The only difference between this one
       and 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 ("IO::Capture::ErrorMessages" and "IO::Capture::Stderr") are
       currently identical, and	"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 "IO::Capture" as a base, read on.

       If one of these modules takes care of your problem, install it and have

       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);

       Using it	in this	script

	   use strict;
	   use warnings;
	   use MyPackage;

	   my $capture = MyPackage->new();
	   print "The quick brown fox jumped over ...";
	   print "garden wall";
	   print "The quick red	fox jumped over	...";
	   print "garden wall";
	   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 ...

       Before starting your own	sub-class, be sure to read through
       IO::Capture.  Pay special attention to the internal methods that	are
       only defined as abstract	methods	in "IO::Capture".  For examples, look
       at the sub-classes included with	this distribution.
       ("IO::Capture::Stdout", "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	"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;

       Lets say	you don't want to capture 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 "IO::Capture::Stderr" as
       the base	and overriding "_retrieve_captured_text" like in "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 "new()" method and have the arguments passed in as an
       anonymous array.	 See the "IO::Capture::Stderr" module for an example.

       Please report bugs on

       Special thanks to  James	E Keenan for many bug fixes and	tests he

       Mark Reynolds reynolds<at>

       Note: "Change <at" to 'at' sign.>

       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.

perl v5.32.1			  2005-04-29	      IO::Capture::Overview(3)


Want to link to this manual page? Use this URL:

home | help