develooper Front page | perl.perl5.porters | Postings from September 2014

[perl #35129] Typeglob prototype swallowing extra arguments?

Thread Previous | Thread Next
From:
Father Chrysostomos via RT
Date:
September 7, 2014 21:46
Subject:
[perl #35129] Typeglob prototype swallowing extra arguments?
Message ID:
rt-4.0.18-22379-1410126367-1274.35129-15-0@perl.org
On Mon May 02 10:09:54 2005, rgarciasuarez@mandriva.com wrote:
> schwern (via RT) wrote:
> > This code compiles and executes.
> >
> > #!/usr/bin/perl -w
> >
> > sub foo {}
> >
> > sub wrap (*) { }
> >
> > wrap foo  pre => sub { print "Args: @_\n" };
> 
> Or, more concisely for illustrations purposes,
>     wrap foo 1, 2;
> 
> > Note the missing comma after "wrap foo".  B::Deparse reveals that
> > everything
> > after "foo" is being somehow swept away.
> >
> > $ perl -MO=Deparse foo.plx
> > BEGIN { $^W = 1; }
> > sub foo {
> >
> > }
> > sub wrap (*) {
> >
> > }
> > &wrap('foo');
> > foo.plx syntax OK
> >
> >
> > Where'd pre go?
> 
> A bit of investigation shows that the parser first thinks that 1 and 2
> are arguments to foo(), but then it notices the prototype of wrap and
> converts foo to a bareword, discarding its arguments. Somehow.

Oh, it’s worse than that.

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

If ‘foo’ is supposed to be a bareword, where did the ‘Foo::’ prefix come from?  Only within the main package does it leave the word as it was.

And it’s not very consistent, either:

$\="\n";
sub foo1 () { 3 }
sub foo2 () { return 4 }
sub bar(*) { print for @_ };
bar foo1;
bar foo2;
__END__
3
foo2

$ perl5.14.4 -le 'sub f(){"x"x3} sub bar(*){print for @_} bar f'
f
$ perl5.18.1 -le 'sub f(){"x"x3} sub bar(*){print for @_} bar f'
xxx

(And that only because x is now subject to constant folding, which was only supposed to speed things up, not change behaviour.)

And the whole point of prototypes to begin with was to allow custom subroutines to imitate the syntax of built-in functions.  But built-in functions that take bareword filehandles allow subroutines to override the bareword interpretation.

What’s worse is that this is preventing me from optimising GVs away for most functions, which would bring about significant memory savings.

So, I wonder: Can we stop * prototypes from trying to change sub calls retroactively back into bare words?  Or will that break too many things?

-- 

Father Chrysostomos


---
via perlbug:  queue: perl5 status: open
https://rt.perl.org/Ticket/Display.html?id=35129

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About