This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Stop barewords from trumping subs with (*) proto
authorFather Chrysostomos <sprout@cpan.org>
Tue, 9 Sep 2014 05:37:46 +0000 (22:37 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 9 Sep 2014 05:37:46 +0000 (22:37 -0700)
commitcfc7ef1544efe7a47158840b7ae10976abeff21b
treec82c152570497a205cbea44ff60998d5070c1581
parentdc279b5a1db1232422bb5ee38bf55ca8729210f7
Stop barewords from trumping subs with (*) proto

The splat prototype was allowing barewords to take precedence over
sub calls, if those sub calls did not parenthesize the argument list.

But it was rather buggy and inconsistent:

$ perl -le 'sub splat(*){print @_} sub foo; splat main::foo'
foo

What happened to main::?

$ perl -le 'package Foo; sub splat(*){print @_} sub foo; splat foo'
Foo::foo

Where did the prefix come from?

And constant subroutines were exempt from this, but whether a subrou-
tine is constant may change between versions:

$ perl5.14.4 -le 'sub splat(*){print @_} sub foo(){"x"x3}; splat foo'
foo
$ perl5.18.1 -le 'sub splat(*){print @_} sub foo(){"x"x3}; splat foo'
xxx

because infix x is now subject to constant folding.

Also:

$ perl5.18.1 -le 'sub splat(*){print @_} BEGIN {$::{foo}=*bar}sub bar; splat foo'
bar

I know this is a naughty example, because it’s fiddling with the sym-
bol table, but if the splat gets confused by that, then something is
quite wrong with its implementation.

Furthermore, one of the stated purposes of prototypes is to enable
custom subroutines to mimic the syntax of built-in functions.  But
*all* the built-in functions that take filehandles allow subroutines
to take precedence over barewords.

This commit allows all subroutines as arguments to the * prototype
to take precedence over barewords, just as constant subroutines
have till now.

This also fixes #35129, because the mechanism that was accidentally
swallowing arguments is now gone.
op.c
t/comp/proto.t