File Coverage

blib/lib/File/Replace/Inplace.pm
Criterion Covered Total %
statement 82 82 100.0
branch 26 26 100.0
condition 6 6 100.0
subroutine 15 15 100.0
pod 0 2 0.0
total 129 131 98.4


line stmt bran cond sub pod time code
1             #!perl
2             package File::Replace::Inplace;
3 8     8   108031 use warnings;
  8         15  
  8         256  
4 8     8   44 use strict;
  8         15  
  8         154  
5 8     8   37 use Carp;
  8         16  
  8         3260  
6              
7             # For AUTHOR, COPYRIGHT, AND LICENSE see the bottom of this file
8              
9             our $VERSION = '0.14';
10              
11             our @CARP_NOT = qw/ File::Replace /;
12              
13             sub new { ## no critic (RequireArgUnpacking)
14 26     26 0 175534 my $class = shift;
15 26 100       223 croak "Useless use of $class->new in void context" unless defined wantarray;
16 25 100       228 croak "$class->new: bad number of args" if @_%2;
17 24         134 my %args = @_; # really just so we can inspect the debug option
18             my $self = {
19             _debug => ref($args{debug}) ? $args{debug} : ( $args{debug} ? *STDERR{IO} : undef),
20             _h_argv => *ARGV{IO},
21 24 100       157 };
    100          
22 24         44 tie *{$self->{_h_argv}}, 'File::Replace::Inplace::TiedArgv', @_;
  24         203  
23 23         62 bless $self, $class;
24 23         112 $self->_debug("$class->new: tied ARGV\n");
25 23         99 return $self;
26             }
27             *_debug = \&File::Replace::_debug; ## no critic (ProtectPrivateVars)
28             sub cleanup {
29 26     26 0 55 my $self = shift;
30 26 100 100     81 if ( defined($self->{_h_argv}) && defined( my $tied = tied(*{$self->{_h_argv}}) ) ) {
  24         134  
31 21 100       112 if ( $tied->isa('File::Replace::Inplace::TiedArgv') ) {
32 20         141 $self->_debug(ref($self)."->cleanup: untieing ARGV\n");
33 20         31 untie *{$self->{_h_argv}};
  20         119  
34             }
35 21         50 delete $self->{_h_argv};
36             }
37 26         49 delete $self->{_debug};
38 26         74 return 1;
39             }
40 23     23   88188 sub DESTROY { return shift->cleanup }
41              
42             {
43             ## no critic (ProhibitMultiplePackages)
44             package # hide from pause
45             File::Replace::Inplace::TiedArgv;
46 8     8   70 use Carp;
  8         16  
  8         451  
47 8     8   539 use File::Replace;
  8         38  
  8         459  
48            
49             BEGIN {
50 8     8   3689 require Tie::Handle::Argv;
51 8         5018 our @ISA = qw/ Tie::Handle::Argv /; ## no critic (ProhibitExplicitISA)
52             }
53            
54             # this is mostly the same as %NEW_KNOWN_OPTS from File::Replace,
55             # except without "in_fh" (note "debug" is also passed to the superclass)
56             my %TIEHANDLE_KNOWN_OPTS = map {$_=>1} qw/ debug layers create chmod
57             perms autocancel autofinish backup files filename /;
58            
59             sub TIEHANDLE { ## no critic (RequireArgUnpacking)
60 26 100 100 26   1818 croak __PACKAGE__."->TIEHANDLE: bad number of args" unless @_ && @_%2;
61 24         80 my ($class,%args) = @_;
62 24         92 for (keys %args) { croak "$class->tie/new: unknown option '$_'"
63 30 100       232 unless $TIEHANDLE_KNOWN_OPTS{$_} }
64 23 100       49 my %superargs = map { exists($args{$_}) ? ($_=>$args{$_}) : () }
  69         188  
65             qw/ files filename debug /;
66 23         59 delete @args{qw/ files filename /};
67 23         118 my $self = $class->SUPER::TIEHANDLE( %superargs );
68 23         53 $self->{_repl_opts} = \%args;
69 23         67 return $self;
70             }
71            
72             sub OPEN {
73 48     48   836 my $self = shift;
74 48 100       367 croak "bad number of arguments to open" unless @_==1;
75 46         74 my $filename = shift;
76 46 100       100 if ($filename eq '-') {
77 1         28 $self->_debug(ref($self).": Reading from STDIN, writing to STDOUT");
78 1         8 $self->set_inner_handle(*STDIN{IO});
79 1         4 select(STDOUT); ## no critic (ProhibitOneArgSelect)
80             }
81             else {
82 45         62 $self->{_repl} = File::Replace->new($filename, %{$self->{_repl_opts}} );
  45         309  
83 44         138 $self->set_inner_handle($self->{_repl}->in_fh);
84 44         117 *ARGVOUT = $self->{_repl}->out_fh; ## no critic (RequireLocalizedPunctuationVars)
85 44         116 select(ARGVOUT); ## no critic (ProhibitOneArgSelect)
86             }
87 45         137 return 1;
88             }
89            
90             sub inner_close {
91 49     49   76 my $self = shift;
92 49 100       129 if ( $self->{_repl} ) {
93 43         141 $self->{_repl}->finish;
94 43         198 $self->{_repl} = undef;
95             }
96 49         122 return 1;
97             }
98            
99             sub sequence_end {
100 21     21   32 my $self = shift;
101 1         4 $self->set_inner_handle(\do{local*HANDLE;*HANDLE}) ## no critic (RequireInitializationForLocalVars)
  1         5  
102 21 100       79 if $self->innerhandle==*STDIN{IO};
103 21         49 select(STDOUT); ## no critic (ProhibitOneArgSelect)
104 21         37 return;
105             }
106            
107             sub UNTIE {
108 22     22   6064 my $self = shift;
109 22         55 select(STDOUT); ## no critic (ProhibitOneArgSelect)
110 22         90 delete @$self{ grep {/^_[^_]/} keys %$self };
  149         425  
111 22         96 return $self->SUPER::UNTIE(@_);
112             }
113            
114             sub DESTROY {
115 23     23   38 my $self = shift;
116 23         48 select(STDOUT); ## no critic (ProhibitOneArgSelect)
117             # File::Replace destructor will warn on unclosed file
118 23         58 delete @$self{ grep {/^_[^_]/} keys %$self };
  6         34  
119 23         62 return $self->SUPER::DESTROY(@_);
120             }
121            
122             }
123              
124             1;
125             __END__