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   460 use strict;
  11         26  
  11         712  
3 8     8   41 use warnings;
  8         19  
  8         324  
4              
5             our $VERSION = '0.000007';
6              
7 8     8   46 use Carp qw/cluck/;
  8         22  
  8         411  
8 8     8   575 use PerlIO;
  8         32  
  8         72  
9              
10             BEGIN {
11             my $maker = sub {
12 19         55 my ($pkg) = @_;
13 19         48 my ($open, $layers, $binmode);
14              
15 19         40 my $ok = eval "#line ${ \__LINE__ } \"${ \__FILE__ }\"\n
  19         70  
  19         1209  
16             package $pkg;" . '
17              
18             $open = sub {
19 8     8   67 no strict q(refs);
  8     8   18  
  8         1151  
  8         75  
  8         20  
  8         1077  
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       86 die "Eval failed for ${pkg}: $@" unless $ok;
32 19         126 return [$open, $layers, $binmode];
33 8     8   45 };
34              
35 8         19 my %opens;
36             my $new_open = sub (*;$@) {
37 36     36   416603 my ($in, @args) = @_;
38              
39 36         109 my $caller = caller;
40              
41 36   66     208 $opens{$caller} ||= $maker->($caller);
42              
43 36         66 my @keep_layers;
44              
45 36 100       172 if ($args[0] =~ m/^(\+?>{1,2})\&(.*)$/) {
46 13   66     57 my $handle = $2 || $args[1];
47              
48 13         50 my $is_fileno = $handle =~ m/^\d+$/;
49              
50 13         41 my @layers = $opens{$caller}->[1]->($handle);
51 13         34 @keep_layers = grep { $_ ne 'via' } @layers;
  28         68  
52              
53 13 100 100     58 if (!$is_fileno && @layers != @keep_layers) {
54 6         12 my $fileno;
55 6 100       25 if (ref($handle) eq 'GLOB') {
    50          
56 2         9 $fileno = fileno($handle);
57             }
58             elsif ($handle =~ m/^\d+$/) {
59 0         0 $fileno = $handle;
60             }
61             else {
62 8     8   2534 no strict 'refs';
  8         22  
  8         258  
63 8     8   38 no warnings 'once';
  8         19  
  8         2005  
64 4 100       20 $fileno = $handle =~ m/^\*(.*)$/ ? fileno(\*{$1}) : fileno(\*{"$caller\::$handle"});
  2         11  
  2         10  
65             }
66              
67 6         79 $args[0] =~ s/\Q$handle\E$//;
68 6         19 $args[1] = $fileno;
69             }
70             else {
71 7         16 @keep_layers = ();
72             }
73             }
74              
75             # Need to pass $_[0] in for magic.
76 36         124 my $out = $opens{$caller}->[0]->($_[0], @args);
77 36 50       175 return $out unless defined $out;
78              
79 36 100       148 if (@keep_layers) {
80 6         16 my %have = map {$_ => 1} $opens{$caller}->[1]->($_[0]);
  12         36  
81 6         13 my $binmode = join '' => map ":$_", grep { !$have{$_} } @keep_layers;
  18         47  
82 6 50       25 $opens{$caller}->[2]->($_[0], $binmode) if $binmode;
83             }
84 36         150 return $out;
85 8         44 };
86              
87 8         30 bless $new_open, __PACKAGE__;
88              
89 8     8   69 no warnings 'once';
  8         15  
  8         303  
90 8         25 *CORE::GLOBAL::open = $new_open;
91              
92             # Make sure the global reference is the only reference
93 8         541 $new_open = undef;
94             }
95              
96             my $WE_CARE = 1;
97 8     8   53361 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__