roho has asked for the wisdom of the Perl Monks concerning the following question:

I have not used bareword filehandles since lexical filehandles were made available. While upgrading a Perl program from bareword filehandles to lexical filehandles I noticed an inconsistency using heredocs. Bareword filehandles in heredocs work fine with a space following the "<<", but lexical filehandles in heredocs generate an error with a space following the "<<".

Since bareword filehandles are due to be deprecated, this may not be a pressing issue. I'm posting this so that others who may run into the same situation do not have to spend the debugging time tracking down this inconsistency.

The following code shows the inconsistency:

#!/usr/bin/perl use strict; use warnings; my $HFILE; my $hfile = 'foo.txt'; # GOOD ##################################################################### # Bareword filehandle works with space following heredoc "<<". ##################################################################### open(HFILE, '>', $hfile) or die "Error opening help file $hfile: $!\n" +; print HFILE << "EOT"; Usage: foo.pl Options: -------- -h Display help information. EOT # BAD ##################################################################### # Lexical filehandle does NOT work with space following heredoc "<<". ##################################################################### open($HFILE, '>', $hfile) or die "Error opening help file $hfile: $!\n +"; print $HFILE << "EOT"; Usage: foo.pl Options: -------- -h Display help information. EOT

"It's not how hard you work, it's how much you get done."

Replies are listed 'Best First'.
Re: Heredoc Inconsistency: Bareword Filehandle vs Lexical Filehandle
by haukex (Archbishop) on Jun 09, 2022 at 19:55 UTC
    $ cat 11144614.pl #!/usr/bin/env perl use warnings; use strict; my $hfile = 'foo.txt'; # GOOD open(HFILE, '>', $hfile) or die "$hfile: $!"; print HFILE << "#EOT"; #Usage: foo.pl #EOT # BAD open(my $HFILE, '>', $hfile) or die "$hfile: $!"; print $HFILE << "#EOT"; #Usage: foo.pl #EOT # GOOD open($HFILE, '>', $hfile) or die "$hfile: $!"; print {$HFILE} << "#EOT"; #Usage: foo.pl #EOT $ perl 11144614.pl Argument "#EOT" isn't numeric in left bitshift (<<) at 11144614.pl lin +e 15. 10294240 $ perl -MO=Deparse,-p 11144614.pl use warnings; use strict; (my $hfile = 'foo.txt'); (open(HFILE, '>', $hfile) or die("${hfile}: $!")); print(HFILE "#Usage: foo.pl\n"); (open(my $HFILE, '>', $hfile) or die("${hfile}: $!")); print(($HFILE << '#EOT')); (open($HFILE, '>', $hfile) or die("${hfile}: $!")); print({$HFILE;} "#Usage: foo.pl\n"); 11144614.pl syntax OK

    Indirect Object Syntax strikes again... and from print:

    NOTE: If FILEHANDLE is a variable and the next token is a term, it may be misinterpreted as an operator unless you interpose a + or put parentheses around the arguments.

    Update: -MO=Deparse,-p makes it even more obvious.

      In such a case I'd rather prefer direct object syntax.

      C:\tmp>perl use warnings; use strict; my $hfile = 'foo.txt'; my $HFILE; # GOOD open($HFILE, '>', $hfile) or die "$hfile: $!"; $HFILE->print(<< "#EOT"); #Usage: foo.pl #EOT __END__ C:\tmp>type foo.txt #Usage: foo.pl

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery