File Coverage

blib/lib/Test2/Plugin/OpenFixPerlIO.pm
Criterion Covered Total %
statement 71 73 97.2
branch 15 22 68.1
condition 7 12 58.3
subroutine 12 13 92.3
pod n/a
total 105 120 87.5


line stmt bran cond sub pod time code
1             package Test2::Plugin::OpenFixPerlIO;
2 11     11   596 use strict;
  11         27  
  11         581  
3 8     8   68 use warnings;
  8         22  
  8         367  
4              
5             our $VERSION = '0.000009';
6              
7 8     8   53 use Carp qw/cluck/;
  8         20  
  8         443  
8 8     8   836 use PerlIO;
  8         41  
  8         77  
9              
10             BEGIN {
11 8 50   8   61 return if $] >= 5.027001;
12              
13             my $maker = sub {
14 19         66 my ($pkg) = @_;
15 19         52 my ($open, $layers, $binmode);
16              
17 19         60 my $ok = eval "#line ${ \__LINE__ } \"${ \__FILE__ }\"\n
  19         181  
  19         1055  
18             package $pkg;" . '
19              
20             $open = sub {
21 8     8   65 no strict q(refs);
  8     8   21  
  8         1222  
  8         85  
  8         25  
  8         1093  
22             return CORE::open($_[0]) if @_ == 1;
23             return CORE::open($_[0], $_[1]) if @_ == 2;
24             return CORE::open($_[0], $_[1], @_[2 .. $#_]);
25             };
26              
27             $layers = sub { PerlIO::get_layers($_[0]) };
28              
29             $binmode = sub { binmode($_[0], $_[1]) };
30              
31             1;
32             ';
33 19 50       91 die "Eval failed for ${pkg}: $@" unless $ok;
34 19         171 return [$open, $layers, $binmode];
35 8         45 };
36              
37 8         22 my %opens;
38             my $new_open = sub (*;$@) {
39 38     38   458907 my ($in, @args) = @_;
40              
41 38         142 my $caller = caller;
42              
43 38   66     248 $opens{$caller} ||= $maker->($caller);
44              
45 38         115 my @keep_layers;
46              
47 38 100       224 if ($args[0] =~ m/^(\+?>{1,2})\&(.*)$/) {
48 13   66     82 my $handle = $2 || $args[1];
49              
50 13         59 my $is_fileno = $handle =~ m/^\d+$/;
51              
52 13         42 my @layers = $opens{$caller}->[1]->($handle);
53 13         39 @keep_layers = grep { $_ ne 'via' } @layers;
  28         74  
54              
55 13 100 100     65 if (!$is_fileno && @layers != @keep_layers) {
56 6         10 my $fileno;
57 6 100       24 if (ref($handle) eq 'GLOB') {
    50          
58 2         7 $fileno = fileno($handle);
59             }
60             elsif ($handle =~ m/^\d+$/) {
61 0         0 $fileno = $handle;
62             }
63             else {
64 8     8   3336 no strict 'refs';
  8         32  
  8         375  
65 8     8   58 no warnings 'once';
  8         19  
  8         2505  
66 4 100       17 $fileno = $handle =~ m/^\*(.*)$/ ? fileno(\*{$1}) : fileno(\*{"$caller\::$handle"});
  2         10  
  2         12  
67             }
68              
69 6         86 $args[0] =~ s/\Q$handle\E$//;
70 6         21 $args[1] = $fileno;
71             }
72             else {
73 7         19 @keep_layers = ();
74             }
75             }
76              
77             # Need to pass $_[0] in for magic.
78 38         140 my $out = $opens{$caller}->[0]->($_[0], @args);
79 38 50       194 return $out unless defined $out;
80              
81 38 100       143 if (@keep_layers) {
82 6         15 my %have = map {$_ => 1} $opens{$caller}->[1]->($_[0]);
  12         50  
83 6         15 my $binmode = join '' => map ":$_", grep { !$have{$_} } @keep_layers;
  18         50  
84 6 50       23 $opens{$caller}->[2]->($_[0], $binmode) if $binmode;
85             }
86 38         167 return $out;
87 8         70 };
88              
89 8         41 bless $new_open, __PACKAGE__;
90              
91 8     8   76 no warnings 'once';
  8         21  
  8         431  
92 8         31 *CORE::GLOBAL::open = $new_open;
93              
94             # Make sure the global reference is the only reference
95 8         799 $new_open = undef;
96             }
97              
98             my $WE_CARE = 1;
99 8     8   58153 END { $WE_CARE = 0 };
100             sub DESTROY {
101 0 0 0 0     cluck "DESTROYED 'CORE::GLOBAL::open' override before it was time!" if $WE_CARE && !$^C;
102             };
103              
104             1;
105              
106             __END__