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