Reputation: 21714
In non-strict mode of Perl, barewords could be recognized as string, like below:
$x = hello;
print $x;
But it seems barewords cannot be passed to print directly, like below one doesn't output the string. Why are they different?
print hello;
Upvotes: 2
Views: 72
Reputation: 85907
In cases like this, the B::Deparse
module can be very helpful:
$ perl -MO=Deparse -e 'print hello;'
print hello $_;
-e syntax OK
As you see, it interprets the identifier as a filehandle and takes the value to be printed from $_
.
Upvotes: 6
Reputation: 386706
An identifier is only a bareword if it has no other meaning.
A word that has no other interpretation in the grammar will be treated as if it were a quoted string. These are known as "barewords".
So, for example, there are no barewords in the following program:
sub f { print STDOUT "f()\n"; }
X: f;
In other circumstances, all of sub
, f
, print
, STDOUT
and X
could be barewords, but they all have other meanings here. I could add use strict;
, and it'll still work fine.
In your code, you used print hello
as I used print STDOUT
. If an identifier follows print
, you are using the print FILEHANDLE LIST
syntax of print
, where the identifier is the name of a file handle.
Upvotes: 2
Reputation: 755094
Barewords should be avoided like the plague they are. Personally, I'll continue to avoid them all the time. They're a relic left over from the wild west days of Perl (circa 1990) and would have been eliminated from the language except for the need to maintain backwards compatibility.
In any case, in that context, it prints $_
to the file handle hello
, doesn't it? That's the sort of reason why barewords are worth avoiding. (Compare: print STDERR "Hello\n";
and print STDERR;
, and print hello;
).
For example:
open hello, ">junk.out";
while (<>)
{
print STDERR "Hello\n";
print STDERR;
print hello;
}
Sample run:
$ perl hello.pl
abc
Hello
abc
def
Hello
def
$ cat junk.out
abc
def
$
In case it isn't clear, I typed one line of abc
, which was followed by Hello
and abc
on standard error; then I typed def
, which was followed by Hello
and def
on standard error. I typed Control-D to indicate EOF, and showed the contents of the file junk.out
(which didn't exist before I ran the script). It contained the two lines that I'd typed.
So, don't use barewords — they're confusing. And do use use strict;
and use warnings;
so that you have less opportunity to be confused.
Upvotes: 3