File Coverage

blib/lib/IO/Tee.pm
Criterion Covered Total %
statement 93 134 69.4
branch 19 36 52.7
condition 1 5 20.0
subroutine 23 43 53.4
pod 0 26 0.0
total 136 244 55.7


line stmt bran cond sub pod time code
1             package IO::Tee;
2              
3             require 5.006;
4 1     1   579 use strict;
  1         1  
  1         25  
5 1     1   4 use warnings;
  1         1  
  1         27  
6              
7 1     1   391 use parent 'IO::Handle';
  1         291  
  1         4  
8              
9 1     1   5926 use Carp;
  1         2  
  1         47  
10 1     1   5 use Symbol;
  1         2  
  1         50  
11 1     1   5 use IO::Handle;
  1         2  
  1         30  
12 1     1   462 use IO::File;
  1         1632  
  1         1287  
13              
14             our $VERSION = '0.65';
15              
16             # Constructor -- bless array reference into our class
17              
18             sub new
19             {
20 7     7 0 11134 my $class = shift;
21 7         18 my $self = gensym;
22 7         104 @{*$self} = map {
23 7 100       82 ! ref($_) ? IO::File->new($_)
  11 100       146  
    50          
    50          
24             : ref($_) eq 'ARRAY' ? IO::File->new(@$_)
25             : ref($_) eq 'GLOB' ? bless $_, 'IO::Handle'
26             : $_ or return undef } @_;
27 7         15 bless $self, $class;
28 7         34 tie *$self, $class, $self;
29 7         29 return $self;
30             }
31              
32             # Return a list of all associated handles
33              
34             sub handles
35             {
36 0     0 0 0 @{*{$_[0]}};
  0         0  
  0         0  
37             }
38              
39             # Proxy routines for various IO::Handle and IO::File operations
40              
41             sub _method_return_success
42             {
43 2     2   13 my $method = (caller(1))[3];
44 2         12 $method =~ s/.*:://;
45              
46 2         5 my $self = shift;
47 2         3 my $ret = 1;
48 2 50       2 foreach my $fh (@{*$self}) { undef $ret unless $fh->$method(@_) }
  2         6  
  4         37  
49 2         38 return $ret;
50             }
51              
52 1     1 0 17 sub close { _method_return_success(@_) }
53 0     0 0 0 sub truncate { _method_return_success(@_) }
54 0     0 0 0 sub write { _method_return_success(@_) }
55 0     0 0 0 sub syswrite { _method_return_success(@_) }
56 0     0 0 0 sub format_write { _method_return_success(@_) }
57 0     0 0 0 sub fcntl { _method_return_success(@_) }
58 0     0 0 0 sub ioctl { _method_return_success(@_) }
59 1     1 0 165 sub flush { _method_return_success(@_) }
60 0     0 0 0 sub clearerr { _method_return_success(@_) }
61 0     0 0 0 sub seek { _method_return_success(@_) }
62              
63             sub formline
64             {
65 0     0 0 0 my $self = shift;
66 0         0 my $picture = shift;
67 0         0 local($^A) = $^A;
68 0         0 local($\) = "";
69 0         0 formline($picture, @_);
70              
71 0         0 my $ret = 1;
72 0 0       0 foreach my $fh (@{*$self}) { undef $ret unless print $fh $^A }
  0         0  
  0         0  
73 0         0 return $ret;
74             }
75              
76             sub _state_modify
77             {
78 1     1   13 my $method = (caller(1))[3];
79 1         9 $method =~ s/.*:://;
80 1 50       5 croak "$method values cannot be retrieved collectively" if @_ <= 1;
81              
82 1         2 my $self = shift;
83 1 50       3 if (ref $self)
84             {
85 1         2 foreach my $fh (@{*$self}) { $fh->$method(@_) }
  1         3  
  2         60  
86             }
87             else
88             {
89 0         0 IO::Handle->$method(@_);
90             }
91             # Note that we do not return any "previous value" here
92             }
93              
94 1     1 0 9 sub autoflush { _state_modify(@_) }
95 0     0 0 0 sub output_field_separator { _state_modify(@_) }
96 0     0 0 0 sub output_record_separator { _state_modify(@_) }
97 0     0 0 0 sub format_page_number { _state_modify(@_) }
98 0     0 0 0 sub format_lines_per_page { _state_modify(@_) }
99 0     0 0 0 sub format_lines_left { _state_modify(@_) }
100 0     0 0 0 sub format_name { _state_modify(@_) }
101 0     0 0 0 sub format_top_name { _state_modify(@_) }
102 0     0 0 0 sub format_line_break_characters { _state_modify(@_) }
103 0     0 0 0 sub format_formfeed { _state_modify(@_) }
104              
105             sub input_record_separator
106             {
107 1     1 0 18 my $self = shift;
108 1 50       6 my $ret = (ref $self ? ${*$self}[0] : 'IO::Handle')
  0         0  
109             ->input_record_separator(@_);
110 1         12 $ret; # This works around an apparent bug in Perl 5.004_04
111             }
112              
113             sub input_line_number
114             {
115 0     0 0 0 my $self = shift;
116 0         0 my $ret = ${*$self}[0]->input_line_number(@_);
  0         0  
117 0         0 $ret; # This works around an apparent bug in Perl 5.004_04
118             }
119              
120             # File handle tying interface
121              
122             sub TIEHANDLE
123             {
124 7     7   16 my ($class, $self) = @_;
125 7         18 return bless *$self{ARRAY}, $class;
126             }
127              
128             sub PRINT
129             {
130 5     5   299 my $self = shift;
131 5         6 my $ret = 1;
132 5 50       10 foreach my $fh (@$self) { undef $ret unless print $fh @_ }
  8         134  
133 5         15 return $ret;
134             }
135              
136             sub PRINTF
137             {
138 2     2   36 my $self = shift;
139 2         11 my $fmt = shift;
140 2         3 my $ret = 1;
141 2 50       3 foreach my $fh (@$self) { undef $ret unless printf $fh $fmt, @_ }
  4         32  
142 2         6 return $ret;
143             }
144              
145             sub _multiplex_input
146             {
147 5     5   13 my ($self, $input) = @_;
148 5         7 my $ret = 1;
149 5 50       9 if (length $input)
150             {
151 5         12 for (my $i = 1; $i < @$self; ++$i)
152             {
153 4 50       5 undef $ret unless print {$self->[$i]} $input;
  4         25  
154             }
155             }
156 5         8 $ret;
157             }
158              
159             sub READ
160             {
161 1     1   26 my $self = shift;
162 1         17 my $bytes = $self->[0]->read(@_);
163 1 50       27 $bytes and $self->_multiplex_input(substr($_[0], $_[2], $bytes));
164 1         3 $bytes;
165             }
166              
167             sub READLINE
168             {
169 2     2   118 my $self = shift;
170 2         4 my $infh = $self->[0];
171 2 50       13 if (wantarray)
172             {
173 0         0 my @data;
174             my $data;
175 0   0     0 while (defined($data = <$infh>) and length($data))
176             {
177 0         0 push @data, $data;
178 0         0 $self->_multiplex_input($data);
179             }
180 0         0 @data;
181             }
182             else
183             {
184 2         62 my $data = <$infh>;
185 2 50       10 defined $data and $self->_multiplex_input($data);
186 2         26 $data;
187             }
188             }
189              
190             sub GETC
191             {
192 1     1   25 my $self = shift;
193 1         22 my $data = getc($self->[0]);
194 1 50       9 defined $data and $self->_multiplex_input($data);
195 1         4 $data;
196             }
197              
198             sub sysread
199             {
200 1     1 0 6 my $self = shift;
201 1         2 my $bytes = ${*$self}[0]->sysread(@_);
  1         15  
202 1 50 50     20 $bytes and (\@{*$self})->
  1         10  
203             _multiplex_input(substr($_[0], $_[2] || 0, $bytes));
204 1         3 $bytes;
205             }
206              
207             sub EOF
208             {
209 1     1   23 my $self = shift;
210 1         6 return $self->[0]->eof;
211             }
212              
213             1;
214             __END__