File Coverage

blib/lib/Capture/Attribute.pm
Criterion Covered Total %
statement 76 113 67.2
branch 13 40 32.5
condition 2 5 40.0
subroutine 21 21 100.0
pod 1 1 100.0
total 113 180 62.7


line stmt bran cond sub pod time code
1             package Capture::Attribute;
2              
3 2     2   24734 use 5.010;
  2         7  
  2         437  
4 2     2   13 use strict;
  2         2  
  2         109  
5              
6             BEGIN {
7 2     2   5 $Capture::Attribute::AUTHORITY = 'cpan:TOBYINK';
8 2         46 $Capture::Attribute::VERSION = '0.001';
9             }
10              
11 2     2   25988 use Attribute::Handlers;
  2         20065  
  2         17  
12 2     2   1872 use Capture::Attribute::Return;
  2         8  
  2         67  
13 2     2   54519 use Capture::Tiny qw//;
  2         570642  
  2         56  
14 2     2   15 use Carp qw//;
  2         4  
  2         26  
15 2     2   1666 use Sub::Name qw//;
  2         1553  
  2         148  
16              
17             my @importers;
18             sub import
19             {
20 2     2   19 my ($class, %args) = @_;
21 2   33     29 my $caller =
22             $args{-into}
23             || $args{-package}
24             || caller;
25            
26 2     2   15 no strict 'refs';
  2         4  
  2         1688  
27 2         3 push @{"$caller\::ISA"}, __PACKAGE__;
  2         26  
28 2 50       47 push @importers, $caller unless $args{-keep};
29             }
30              
31             my ($make_replacement_coderef, $save_coderef, $saved);
32             BEGIN
33             {
34             $make_replacement_coderef = sub
35             {
36 1         2 my ($orig, $data) = @_;
37              
38 1 50       10 if ($data eq 'STDOUT')
    50          
    50          
    50          
    50          
39             {
40             return sub
41             {
42 0         0 my (@args) = @_;
43 0         0 my $wa = wantarray;
44             my $stdout = Capture::Tiny::capture {
45             $wa ? $save_coderef->(1, my @r = $orig->(@args)) :
46             defined $wa ? $save_coderef->(0, my $r = $orig->(@args)) :
47 0 0       0 do { $orig->(@args); $save_coderef->() } ;
  0 0       0  
  0         0  
48 0         0 };
49 0         0 return $stdout;
50             }
51 0         0 }
52             elsif ($data eq 'STDERR')
53             {
54             return sub
55             {
56 0         0 my (@args) = @_;
57 0         0 my $wa = wantarray;
58             my (undef, $stderr) = Capture::Tiny::capture {
59             $wa ? $save_coderef->(1, my @r = $orig->(@args)) :
60             defined $wa ? $save_coderef->(0, my $r = $orig->(@args)) :
61 0 0       0 do { $orig->(@args); $save_coderef->() } ;
  0 0       0  
  0         0  
62 0         0 };
63 0         0 return $stderr;
64             }
65 0         0 }
66             elsif ($data eq 'MERGED')
67             {
68             return sub
69             {
70 0         0 my (@args) = @_;
71 0         0 my $wa = wantarray;
72             my $merged = Capture::Tiny::capture_merged {
73             $wa ? $save_coderef->(1, my @r = $orig->(@args)) :
74             defined $wa ? $save_coderef->(0, my $r = $orig->(@args)) :
75 0 0       0 do { $orig->(@args); $save_coderef->() } ;
  0 0       0  
  0         0  
76 0         0 };
77 0         0 return $merged;
78             }
79 0         0 }
80             elsif ($data eq 'STDERR,STDOUT')
81             {
82             return sub
83             {
84 0         0 my (@args) = @_;
85 0         0 my $wa = wantarray;
86             my @r = Capture::Tiny::capture {
87             $wa ? $save_coderef->(1, my @r = $orig->(@args)) :
88             defined $wa ? $save_coderef->(0, my $r = $orig->(@args)) :
89 0 0       0 do { $orig->(@args); $save_coderef->() } ;
  0 0       0  
  0         0  
90 0         0 };
91 0 0       0 return wantarray ? reverse(@r[0..1]) : $r[0];
92             }
93 0         0 }
94             elsif ($data eq 'STDOUT,STDERR')
95             {
96             return sub
97             {
98 2     2   10 my (@args) = @_;
99 2         4 my $wa = wantarray;
100             return Capture::Tiny::capture {
101             $wa ? $save_coderef->(1, my @r = $orig->(@args)) :
102             defined $wa ? $save_coderef->(0, my $r = $orig->(@args)) :
103 2 50   2   2418 do { $orig->(@args); $save_coderef->() } ;
  0 100       0  
  0         0  
104 2         126 };
105             }
106 1         8 }
107              
108 0         0 return;
109 2     2   17 };
110            
111             $save_coderef = sub
112             {
113 2 50       44690 if (not scalar @_)
114             {
115 0         0 $saved = Capture::Attribute::Return->new(wasarray => undef);
116 0         0 return;
117             }
118            
119 2         8 my $context = shift;
120 2 100       92 $saved = Capture::Attribute::Return->new(
121             wasarray => $context,
122             value => ($context ? \@_ : $_[0]),
123             );
124             }
125 2         64 }
126              
127             INIT # runs AFTER attributes have been handled.
128             {
129 2     2   12 no strict 'refs';
  2         4  
  2         213  
130 2     2   30 foreach my $caller (@importers)
131             {
132 2         4 @{"$caller\::ISA"} = grep { $_ ne __PACKAGE__ } @{"$caller\::ISA"};
  2         41  
  2         8  
  2         35  
133             }
134 2     2   10 no warnings 'once';
  2         3  
  2         465  
135 2     4   115 *return = sub { $saved };
  4         6742  
136             }
137              
138             sub Capture :ATTR(CODE,RAWDATA)
139             {
140             my (
141 1     1 1 22099 $package,
142             $symbol,
143             $referent,
144             $attr,
145             $data,
146             $phase,
147             $filename,
148             $linenum,
149             ) = @_;
150              
151 1   50     6 $data = uc($data) || (my $default_data = 'STDOUT');
152              
153 1         2 my $orig = *{$symbol}{CODE};
  1         2  
154 1 50       4 my $replacement = $make_replacement_coderef->($orig, $data)
155             or Carp::croak "Unrecognised option string: $data";
156              
157             {
158 2     2   20 no strict 'refs';
  2         4  
  2         59  
  1         2  
159 2     2   10 no warnings 'redefine';
  2         3  
  2         175  
160 1         2 my $subname = sprintf '%s::%s', *{$symbol}{PACKAGE}, *{$symbol}{NAME};
  1         2  
  1         4  
161 1         7 *{$subname} = Sub::Name::subname($subname, $replacement);
  1         5  
162             }
163 2     2   10 }
  2         3  
  2         19  
164              
165             __PACKAGE__
166             __END__