Search code examples
perlbareword

Why is a bareword following the concatenation operator a string in Perl?


Why does Perl (5.30.3 but also no feature ':all') assume a bareword following the concatenation operator . to be a string? For example:

use v5.30;   # or: no feature ':all'; 
use strict;
use warnings;
my $k1 = 'a';
my $k2 = 'b';
print STDOUT $k1 . k2 . "\n";

prints out ak2 (ab was intended), and raises no exceptions about barewords being not allowed here. This is a bug in my script, though not necessarily in Perl.

According to perlglossary, a bareword is a "word sufficiently ambiguous to be deemed illegal under use strict 'subs'." However, since a scalar named $k2 was defined before k2, I'd have thought k2 to be ambiguous enough.

Curiously, an exception is raised with a second bareword:

use v5.30;   # or: no feature ':all';
use strict;
use warnings;
my $k1 = 'a';
my $k2 = 'b';
my $k3 = 'c';
print STDOUT $k1 . k2 . k3  . "\n";

And:

Bareword "k3" not allowed while "strict subs" in use at mwe.pl line 7.
Execution of mwe.pl aborted due to compilation errors.

k3 is not allowed, but k2 is. Why?


Solution

  • It's a bug introduced in 5.28.0 and fixed in 5.32.0.

    A newly-added compile-time optimisation of (usually multiple) string concatenations was skipping the bareword check.