Codebase list libcapture-tiny-perl / 15ade47
generate API subs dynamically; refactor open() calls David Golden 15 years ago
2 changed file(s) with 42 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
1414 our $VERSION = '0.03';
1515 $VERSION = eval $VERSION; ## no critic
1616 our @ISA = qw/Exporter/;
17 our @EXPORT_OK = qw/capture tee/;
17 our @EXPORT_OK = qw/capture capture_merged tee tee_merged/;
1818
1919 my $use_system = $^O eq 'MSWin32';
2020
2121 #--------------------------------------------------------------------------#
22 # Error messages
23 #--------------------------------------------------------------------------#
24
25 sub _redirect_err { return "Error redirecting $_[0]: $!" }
26
27 #--------------------------------------------------------------------------#
28 # bulk filehandle manipulation
29 #--------------------------------------------------------------------------#
22 # filehandle manipulation
23 #--------------------------------------------------------------------------#
24
25 sub _open {
26 open $_[0], $_[1] or die "Error from open( " . join(q{, }, @_) . "): $!";
27 }
3028
3129 sub _copy_std {
3230 my @std = map { IO::Handle->new } 0 .. 2;
33 open $std[0], "<&STDIN" or die _redirect_err("STDIN" );
34 open $std[1], ">&STDOUT" or die _redirect_err("STDOUT");
35 open $std[2], ">&STDERR" or die _redirect_err("STDERR");
31 _open $std[0], "<&STDIN";
32 _open $std[1], ">&STDOUT";
33 _open $std[2], ">&STDERR";
3634 return @std;
3735 }
3836
3937 sub _open_std {
40 open STDIN , "<&" . fileno( $_[0] ) or die _redirect_err("STDIN" );
41 open STDOUT, ">&" . fileno( $_[1] ) or die _redirect_err("STDOUT");
42 open STDERR, ">&" . fileno( $_[2] ) or die _redirect_err("STDERR");
38 _open \*STDIN , "<&" . fileno( $_[0] );
39 _open \*STDOUT, ">&" . fileno( $_[1] );
40 _open \*STDERR, ">&" . fileno( $_[2] );
4341 }
4442
4543 sub _autoflush {
8482 #--------------------------------------------------------------------------#
8583
8684 sub _capture_tee {
87 my ($code, $tee) = @_;
85 my ($tee, $merge, $code) = @_;
8886
8987 my @copy_of_std = _copy_std();
9088 my @captures = ( undef, scalar tempfile(), scalar tempfile() );
9189 my @readers = ( undef, IO::Handle->new, IO::Handle->new );
9290 my @tees = ( undef, IO::Handle->new, IO::Handle->new );
9391 my @pids;
92
93 # if merging, redirect STDERR to STDOUT (and don't capture on STDERR)
94 # _open if ($merge) {
9495
9596 # if teeing, redirect output to teeing subprocesses
9697 if ($tee) {
146147 }
147148
148149 #--------------------------------------------------------------------------#
149 # capture()
150 #--------------------------------------------------------------------------#
151
152 sub capture(&) { ## no critic
153 $_[1] = 0; # no tee
154 goto \&_capture_tee;
155 }
156
157 #--------------------------------------------------------------------------#
158 # tee()
159 #--------------------------------------------------------------------------#
160
161 sub tee(&) { ## no critic
162 $_[1] = 1; # tee
163 goto \&_capture_tee;
150 # create API subroutines from [tee flag, merge flag]
151 #--------------------------------------------------------------------------#
152
153 my %api = (
154 capture => [0,0],
155 capture_merged => [0,1],
156 tee => [1,0],
157 tee_merged => [1,1],
158 );
159
160 for my $sub ( keys %api ) {
161 my $unshift = join q{, }, @{$api{$sub}};
162 eval "sub $sub (&) { unshift \@_, $unshift; goto \\&_capture_tee; }";
164163 }
165164
166165 1;
66 use strict;
77 use warnings;
88
9 use Test::More tests => 1;
9 use Test::More ;
10
11 my @api = qw(
12 capture
13 capture_merged
14 tee
15 tee_merged
16 );
17
18 plan tests => 1 + @api;
1019
1120 require_ok( 'Capture::Tiny' );
1221
22 can_ok('Capture::Tiny', $_) for @api;
23