Problem with here-doc in `print $fh <<'EOF'`: Perl executing the here doc

Viewed 165

(According to https://stackoverflow.com/a/17479551/6607497 it should work, but doesn't) I have some code like this:

use strict;
use warnings;
if (open(my $fh, '>', '/tmp/test')) {
    print $fh << 'TAG';
    BEGIN {
       something;
    }
TAG
    close($fh);
}

If I leave out $fh (which is a file handle opened for output, BTW), the BEGIN block is output correctly (to STDOUT). However when I add $fh, Perl (5.18, 5.26) tried to execute something which causes an run-time error:

Bareword "something" not allowed while "strict subs" in use at /tmp/heredoc2.pl line 6.
syntax error at /tmp/heredoc2.pl line 9, near "FOO
    close"
Execution of /tmp/heredoc2.pl aborted due to compilation errors.

What is wrong?

1 Answers

The details of the problem are interesting (Original Perl was 5.18.2, but using 5.26.1 for the example):

First some code that works without $fh:

#!/usr/bin/perl
use strict;
use warnings;
if (open(my $fh, '>', '/tmp/test')) {
    print << 'FOO_BAR';
BEGIN {
    something;
}
FOO_BAR
    close($fh);
}

perl -c says : /tmp/heredoc.pl syntax OK, but nothing is output!

If I add $fh before <<, I get this error:

Bareword "something" not allowed while "strict subs" in use at /tmp/heredoc.pl line 7.
syntax error at /tmp/heredoc.pl line 10, near "FOO_BAR
    close"
/tmp/heredoc.pl had compilation errors.

Finally if I remove the space before 'FOO_BAR', it works:

#!/usr/bin/perl
use strict;
use warnings;
if (open(my $fh, '>', '/tmp/test')) {
    print $fh <<'FOO_BAR';
BEGIN {
    something;
}
FOO_BAR
    close($fh);
}

> perl -c /tmp/heredoc.pl 
/tmp/heredoc.pl syntax OK
> perl /tmp/heredoc.pl 
> cat /tmp/test
BEGIN {
    something;
}

Maybe the true pitfall is the statement in perlop(1):

           There may not be a space between the "<<" and the identifier,
           unless the identifier is explicitly quoted.  (...)
Related