Reputation: 1211
perl-5.24.0-gcc620 on linux
I have some existing code in a perl module that uses IO::Tee to direct stdout to both a file and the terminal...
use strict;
use IO::Tee;
our $tee;
sub common {
open $tee, ">", "my.log";
$tee = new IO::Tee(\*STDOUT, $tee);
etc...
}
.
.
.
sub some_sub {
print $tee "I want this to go to the log file and the terminal. Works fine.\n";
}
Now, I want to use "some_sub" using a perl script that does not run the "common" sub which does the IO::Tee piece. So $tee will be undefined and I'll get compilation errors when I try to use it.
The hack I did is...
if($tee) {
print $tee "I want to print this\n";
} else {
print "I want to print this";
}
But the print statements are all over the place and I want a more elegant way of dealing with this. What I want to do is something like this...
if(!($tee)) {
$tee = STDOUT;
}
... then leave all the existing "print $tee ..." statements alone.
But this gives me a bareword error because I'm using "use strict"...
Bareword "STDOUT" not allowed while "strict subs" in use at ./change_tee_STDOUT.pl line 4.
If I get rid of the "use strict", it seems to work.
How can I get the functionality of "$tee = STDOUT" while retaining the "use strict" ? I feel that perhaps there is a way to cast STDOUT to a filehandle type, or something like that. Am I close ?
Upvotes: 2
Views: 278
Reputation: 1832
It's better to use a neutral file handle in the functions and connect it to whatever outputs that mode of operation calls for.
use strict;
use diagnostics;
our $OUTPUT;
if ($mode1) {
open $OUTPUT, ">", $file;
}
elsif ($mode2) {
open $OUTPUT, ">&=", *STDOUT;
}
elsif ($mode3) {
my $tee = tee_up("my.log");
open $OUTPUT, ">&=", $tee;
}
else { die; }
sub tee_up {
require IO::Tee;
open my $fh, ">", $_[0];
return IO::Tee->new(\*STDOUT, $fh);
}
sub some_sub {
print $OUTPUT "I want this to go where I want\n";
}
Thanks.
Upvotes: 0
Reputation: 386461
$tee = \*STDOUT; # Reference to a glob containing the IO object.
or
$tee = *STDOUT; # Glob containing the IO object.
or
$tee = *STDOUT{IO}; # Reference to the IO object.
I use the first one. (And you did as well in your existing code!) The second should work just as well. I'm not sure how universally supported the last one is. (Perl itself won't have any problem with it, but XS modules?)
Upvotes: 4