Acme-Throw
view release on metacpan or search on metacpan
t/lib/Capture/Tiny.pm view on Meta::CPAN
push @return, $got{stdout} if $do_stdout;
push @return, $got{stderr} if $do_stderr && ! $do_merge;
push @return, @result;
return wantarray ? @return : $return[0];
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Capture::Tiny - Capture STDOUT and STDERR from Perl, XS or external programs
=head1 VERSION
version 0.23
=head1 SYNOPSIS
use Capture::Tiny ':all';
# capture from external command
($stdout, $stderr, $exit) = capture {
system( $cmd, @args );
};
# capture from arbitrary code (Perl or external)
($stdout, $stderr, @result) = capture {
# your code here
};
# capture partial or merged output
$stdout = capture_stdout { ... };
$stderr = capture_stderr { ... };
$merged = capture_merged { ... };
# tee output
($stdout, $stderr) = tee {
# your code here
};
$stdout = tee_stdout { ... };
$stderr = tee_stderr { ... };
$merged = tee_merged { ... };
=head1 DESCRIPTION
Capture::Tiny provides a simple, portable way to capture almost anything sent
to STDOUT or STDERR, regardless of whether it comes from Perl, from XS code or
from an external program. Optionally, output can be teed so that it is
captured while being passed through to the original filehandles. Yes, it even
works on Windows (usually). Stop guessing which of a dozen capturing modules
to use in any particular situation and just use this one.
=head1 USAGE
The following functions are available. None are exported by default.
=head2 capture
($stdout, $stderr, @result) = capture \&code;
$stdout = capture \&code;
The C<<< capture >>> function takes a code reference and returns what is sent to
STDOUT and STDERR as well as any return values from the code reference. In
scalar context, it returns only STDOUT. If no output was received for a
filehandle, it returns an empty string for that filehandle. Regardless of calling
context, all output is captured -- nothing is passed to the existing filehandles.
It is prototyped to take a subroutine reference as an argument. Thus, it
can be called in block form:
($stdout, $stderr) = capture {
# your code here ...
};
Note that the coderef is evaluated in list context. If you wish to force
scalar context on the return value, you must use the C<<< scalar >>> keyword.
($stdout, $stderr, $count) = capture {
my @list = qw/one two three/;
return scalar @list; # $count will be 3
};
Also note that within the coderef, the C<<< @_ >>> variable will be empty. So don't
use arguments from a surrounding subroutine without copying them to an array
first:
sub wont_work {
my ($stdout, $stderr) = capture { do_stuff( @_ ) }; # WRONG
...
}
sub will_work {
my @args = @_;
my ($stdout, $stderr) = capture { do_stuff( @args ) }; # RIGHT
...
}
Captures are normally done to an anonymous temporary filehandle. To
capture via a named file (e.g. to externally monitor a long-running capture),
provide custom filehandles as a trailing list of option pairs:
my $out_fh = IO::File->new("out.txt", "w+");
my $err_fh = IO::File->new("out.txt", "w+");
capture { ... } stdout => $out_fh, stderr => $err_fh;
The filehandles must be readE<sol>write and seekable. Modifying the files or
filehandles during a capture operation will give unpredictable results.
Existing IO layers on them may be changed by the capture.
When called in void context, C<<< capture >>> saves memory and time by
( run in 1.064 second using v1.01-cache-2.11-cpan-e1769b4cff6 )