File Coverage

blib/lib/Tie/STDOUT.pm
Criterion Covered Total %
statement 23 28 82.1
branch 0 2 0.0
condition 3 6 50.0
subroutine 10 14 71.4
pod n/a
total 36 50 72.0


line stmt bran cond sub pod time code
1             package Tie::STDOUT;
2              
3 1     1   76127 use 5.008;
  1         19  
4              
5 1     1   6 no warnings; # in case they've been turned on
  1         2  
  1         65  
6              
7             $VERSION = '1.0500';
8              
9 1     1   6 use strict;
  1         2  
  1         39  
10              
11             open(REALSTDOUT, ">&STDOUT");
12              
13             # do this late to avoid bogus warning about only using REALSTDOUT once
14 1     1   5 use warnings;
  1         2  
  1         442  
15              
16             =head1 NAME
17              
18             Tie::STDOUT - intercept writes to STDOUT and apply user-defined functions
19             to them.
20              
21             =head1 SYNOPSIS
22              
23             use Tie::STDOUT
24             print => sub {
25             print map { uc } @_;
26             },
27             printf => ...
28             syswrite => ... ;
29              
30             =head1 DESCRIPTION
31              
32             This module intercepts all writes to the STDOUT filehandle and applies
33             whatever function you desire to what would have gone to STDOUT. In the
34             example above, any use of the print() function on this filehandle will
35             have its output transmogrified into upper case.
36              
37             You will have noticed that we blithely print to the default filehandle
38             (which is almost always STDOUT) in the function we supplied. Relax, this
39             doesn't cause an infinite loop, because your functions are always called
40             with a *normal* STDOUT.
41              
42             You may provide up to three user-defined functions which are respectively
43             called whenever you use print(), printf() or syswrite() on the filehandle:
44              
45             =over 4
46              
47             =item print
48              
49             defaults to printing to the real STDOUT;
50              
51             =item printf
52              
53             defaults to passing all parameters through sprintf() and then passing
54             them to whatever the 'print' function is;
55              
56             =item syswrite
57              
58             Defaults to going straight through to the real STDOUT.
59              
60             =back
61              
62             You will note that the default behaviour is exactly the same as it would
63             be without this module.
64              
65             Because we have a sensible default for 'printf' and because syswrite is so
66             rarely used, you will normally only have to provide your own code for
67             'print'.
68              
69             =head1 BUGS
70              
71             Doesn't work on perl 5.6, because it seems that localising tied
72             filehandles doesn't work.
73              
74             =head1 SEE ALSO
75              
76             =over 4
77              
78             =item Capture::Tiny
79              
80             =item IO::Capture::Stdout
81              
82             =item Tie::STDERR
83              
84             =back
85              
86             =head1 FEEDBACK
87              
88             I like to know who's using my code. All comments, including constructive
89             criticism, are welcome. Please email me.
90              
91             =head1 AUTHOR
92              
93             David Cantrell EFE
94              
95             =head1 COPYRIGHT
96              
97             Copyright 2006 David Cantrell
98              
99             This module is free-as-in-speech software, and may be used, distributed,
100             and modified under the same terms as Perl itself.
101              
102             =cut
103              
104             sub import {
105 1     1   17 my $class = shift;
106 1         4 my %params = @_;
107 1         8 tie *STDOUT, $class, %params;
108             }
109              
110             sub TIEHANDLE {
111 1     1   3 my($class, %params) = @_;
112             my $self = {
113 0     0   0 print => $params{print} || sub { print @_; },
114             syswrite => $params{syswrite} || sub {
115 0     0   0 my($buf, $len, $offset) = @_;
116 0 0       0 syswrite(STDOUT, $buf, $len, defined($offset) ? $offset : 0);
117             }
118 1   50     9 };
      50        
119             $self->{printf} = $params{printf} || sub {
120 0     0   0 $self->{print}->(sprintf($_[0], @_[1 .. $#_]))
121 1   50     14 };
122 1         1678 bless($self, $class);
123             }
124              
125             sub _with_real_STDOUT {
126 3     3   82 open(local *STDOUT, ">&REALSTDOUT");
127 3         24 $_[0]->(@_[1 .. $#_]);
128             }
129              
130 1     1   122 sub PRINT { _with_real_STDOUT(shift()->{print}, @_); }
131 1     1   1070 sub PRINTF { _with_real_STDOUT(shift()->{printf}, @_); }
132 1     1   603 sub WRITE { _with_real_STDOUT(shift()->{syswrite}, @_); }
133 0     0     sub BINMODE { binmode(REALSTDOUT, $_[1]); }
134              
135             1;