develooper Front page | perl.perl5.porters | Postings from May 2012

Re: [perl #112732] Subs ending in { @a } return list, not hashref;can Perl defend against this trap?

Thread Previous
From:
Nicholas Clark
Date:
May 3, 2012 02:29
Subject:
Re: [perl #112732] Subs ending in { @a } return list, not hashref;can Perl defend against this trap?
Message ID:
20120503092943.GQ9069@plum.flirble.org
On Thu, May 03, 2012 at 11:10:43AM +0200, H.Merijn Brand wrote:
> On Wed, 02 May 2012 12:39:45 -0700, Jim Avera (via RT)
> <perlbug-followup@perl.org> wrote:
> 
> > In the following, Perl silently parses the {...} in the last line
> > of each sub as a BLOCK rather than an anonymous-hash constructor.
> > The functions return the list (a,1,b,1), not a hahsref
> > as the programmer obviously intended:
> > 
> >    use struct; use warnings;
> >    sub f {
> >      my @keys = ("a","b");
> >      { map{$_ => 1} @keys }
> >    }
> >    sub g { my @a = (a => 1, b => 2); { @a } }
> > 
> > This is a trap.  Can Perl do something to save programmers from it?

We could make return statements mandatory :-)

> > One solution might be to actually recognize when {...} is the last thing 
> > in a sub definition and parse it as an expression in that case.
> 
> This issue comes back every now and then, and whatever way the current
> parsing is modified will break someone elses expectations. The ability
> to unambiguate using a + is easy enough to warrant not to change this

Worse than that, I think it's not possible. Too much lookahead would be needed,
because the parser has to decide early whether the { is a block or a hash
constructor. It's not able to defer that decision until it reaches the }
And, unfortunately, in the example given, the code within the {} is valid
for either interpretation of the {

> > Another might be to warn about *statements* consisting only of 
> > expressions with no side-effects, which would let the user know that a
> > dangling "{ map{$_=>1} @keys }" was not handled by Perl as they expected.
> 
> No. Many people use this to explicitely create a scope, possibly with
> lexical variable, to avoid side effects or force auto-destruction.

I think the key part of the request was that all code *within* the block
had to have no side effects. The use case that you (Merijn) describe would
(I think) always have some statement with side effects.

However, I'm not sure how easy it is to "know" unambiguously whether a
section of the optree has side effects. (I'm going to discount the hidden
side effects of things lile the values read being tied or overloaded)

Nicholas Clark

Thread Previous


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