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   442 use strict;
  1         3  
  1         34  
5 1     1   7 use warnings;
  1         2  
  1         42  
6              
7 1     1   386 use parent 'IO::Handle';
  1         277  
  1         4  
8              
9 1     1   4706 use Carp;
  1         2  
  1         42  
10 1     1   4 use Symbol;
  1         2  
  1         43  
11 1     1   4 use IO::Handle;
  1         2  
  1         26  
12 1     1   257 use IO::File;
  1         1507  
  1         1087  
13              
14             our $VERSION = '0.65';
15              
16             # Constructor -- bless array reference into our class
17              
18             sub new
19             {
20 7     7 0 916 my $class = shift;
21 7         17 my $self = gensym;
22 7         125 @{*$self} = map {
23 7 100       94 ! ref($_) ? IO::File->new($_)
  11 100       169  
    50          
    50          
24             : ref($_) eq 'ARRAY' ? IO::File->new(@$_)
25             : ref($_) eq 'GLOB' ? bless $_, 'IO::Handle'
26             : $_ or return undef } @_;
27 7         18 bless $self, $class;
28 7         37 tie *$self, $class, $self;
29 7         21 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   15 my $method = (caller(1))[3];
44 2         13 $method =~ s/.*:://;
45              
46 2         6 my $self = shift;
47 2         4 my $ret = 1;
48 2 50       4 foreach my $fh (@{*$self}) { undef $ret unless $fh->$method(@_) }
  2         8  
  4         35  
49 2         31 return $ret;
50             }
51              
52 1     1 0 13 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 37 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   11 my $method = (caller(1))[3];
79 1         12 $method =~ s/.*:://;
80 1 50       6 croak "$method values cannot be retrieved collectively" if @_ <= 1;
81              
82 1         4 my $self = shift;
83 1 50       4 if (ref $self)
84             {
85 1         3 foreach my $fh (@{*$self}) { $fh->$method(@_) }
  1         6  
  2         79  
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 10 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 10 my $self = shift;
108 1 50       7 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         23 return bless *$self{ARRAY}, $class;
126             }
127              
128             sub PRINT
129             {
130 5     5   97 my $self = shift;
131 5         6 my $ret = 1;
132 5 50       11 foreach my $fh (@$self) { undef $ret unless print $fh @_ }
  8         46  
133 5         14 return $ret;
134             }
135              
136             sub PRINTF
137             {
138 2     2   32 my $self = shift;
139 2         4 my $fmt = shift;
140 2         3 my $ret = 1;
141 2 50       6 foreach my $fh (@$self) { undef $ret unless printf $fh $fmt, @_ }
  4         25  
142 2         7 return $ret;
143             }
144              
145             sub _multiplex_input
146             {
147 5     5   16 my ($self, $input) = @_;
148 5         7 my $ret = 1;
149 5 50       11 if (length $input)
150             {
151 5         13 for (my $i = 1; $i < @$self; ++$i)
152             {
153 4 50       5 undef $ret unless print {$self->[$i]} $input;
  4         18  
154             }
155             }
156 5         21 $ret;
157             }
158              
159             sub READ
160             {
161 1     1   17 my $self = shift;
162 1         11 my $bytes = $self->[0]->read(@_);
163 1 50       16 $bytes and $self->_multiplex_input(substr($_[0], $_[2], $bytes));
164 1         2 $bytes;
165             }
166              
167             sub READLINE
168             {
169 2     2   90 my $self = shift;
170 2         3 my $infh = $self->[0];
171 2 50       4 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         5 my $data = <$infh>;
185 2 50       7 defined $data and $self->_multiplex_input($data);
186 2         6 $data;
187             }
188             }
189              
190             sub GETC
191             {
192 1     1   18 my $self = shift;
193 1         17 my $data = getc($self->[0]);
194 1 50       6 defined $data and $self->_multiplex_input($data);
195 1         4 $data;
196             }
197              
198             sub sysread
199             {
200 1     1 0 10 my $self = shift;
201 1         3 my $bytes = ${*$self}[0]->sysread(@_);
  1         13  
202 1 50 50     22 $bytes and (\@{*$self})->
  1         13  
203             _multiplex_input(substr($_[0], $_[2] || 0, $bytes));
204 1         5 $bytes;
205             }
206              
207             sub EOF
208             {
209 1     1   17 my $self = shift;
210 1         5 return $self->[0]->eof;
211             }
212              
213             1;
214             __END__