File Coverage

blib/lib/Test2/Plugin/OpenFixPerlIO.pm
Criterion Covered Total %
statement 70 72 97.2
branch 14 20 70.0
condition 7 12 58.3
subroutine 12 13 92.3
pod n/a
total 103 117 88.0


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