Hey now, 21 years after this inspired module was added, I just wanted to note a small bug in the Filter subroutine (in package Filter::Handle). It should be:
sub Filter {
my $fh = shift;
tie *{ $fh }, __PACKAGE__, @_;
}
Note how the subroutine UnFilter uses the shift correctly.
Also, it's a shame that this is no longer on CPAN. But this chunk of module is enough to put into one's "private" library for use. Using a CODE reference, you can duplicate all your STDOUT and STDERR (including any that comes out of perl warnings), like the following:
select STDERR; $|=1;
select STDOUT; $|=1;
use FileHandle;
my $LOG_FH = new FileHandle($logfile, "w");
$LOG_FH->autoflush;
open(DUPOUT, ">&STDOUT") or die "Couldn't dup STDOUT: $!\n";
open(DUPERR, ">&STDERR") or die "Couldn't dup STDERR: $!\n";
use Filter::Handle qw/subs/;
our $FILTER_STDOUT = sub
{ local $_ = "@_";
print DUPOUT $_;
sprintf "[STDOUT]: %s", "@_"
if (defined $LOG_FH && $LOG_FH->opened);
};
our $FILTER_STDERR = sub
{ local $_ = "@_";
print DUPERR $_;
sprintf "[STDERR]: %s", "@_"
if (defined $LOG_FH && $LOG_FH->opened);
};
## Call Filter to tie the filehandles
## Call UnFilter to untie the filehandles (don't care)
Filter \*STDOUT, $LOG_FH, $FILTER_STDOUT;
Filter \*STDERR, $LOG_FH, $FILTER_STDERR;
I like this much better than IO::Tee, because I don't need a custom filehandle to print to to get a logfile of all output. I'm continuing to play around with this and may update this thread more later.