Sometime I have to use the bareword "STDOUT", sometimes the bareword doesn't work and sometimes I can use the bareword or another form. Are there rules, which tell me when I have to choose on form and when another and when I can choose the form?
#!/usr/bin/env perl
use warnings;
use 5.12.0;
use utf8;
print STDOUT "Something\n"; # works
print \*STDOUT "Something\n"; # String found where operator expected
print { STDOUT } "Something\n"; # Bareword "STDOUT" not allowed while "strict subs" in use
print { \*STDOUT } "Something\n" # works
my $fh;
$fh = -t STDOUT ? STDOUT : STDERR; # Bareword "STDOUT"/"STDERR" not allowed while "strict subs" in use
$fh = -t STDOUT ? \*STDOUT : \*STDERR; # works
$fh = -t \*STDOUT ? \*STDOUT : \*STDERR; # works
These are the rules according to my tests:
when use strict subs is in effect, the bareword versions can't be passed as filehandles, presumably because they could be subroutine calls.
The *STDOUT and \*STDOUT versions can be used to pass to functions all the time.
passing one of them to a sub with foo STDOUT (without parentheses) breaks because perl assumes that is STDOUT->foo.
Aside from cases 1 and 3, you can pass them to subs with the bareword verisons as well.
for calls to print, printf etc, you must either use the bareword versions, or use {}. enclosing the filehandle in {} tells perl that yes the first argument is a filehandle, so you can use any form.
For these purposes -t counts as a sub, as do other -X tests that accept filehandles.
When you use {} with print or printf, the part inside {} is a code block; it is evaluated and the result is used as the filehandle. It works with those functions because they are treated specially by perl, in the same way as map and grep.
So follow these rules and you will be okay:
when printing to STDERR or STDOUT explcitly, use the bareword version:
print STDERR "ERRORRRRR\n";
when using a filehandle in any other way, use the * version:
my $isterm = -t *STDOUT;
close(*STDERR);
I tested as far back as perl 5.8.7. This is as far back as I can go right now. The above should work for 5.6 as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With