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

Variable unavailability inconsistency ([perl #113930] Lexical subs)

Thread Next
From:
Father Chrysostomos via RT
Date:
August 3, 2012 16:08
Subject:
Variable unavailability inconsistency ([perl #113930] Lexical subs)
Message ID:
rt-3.6.HEAD-11172-1344035320-1288.113930-14-0@perl.org
This program:

#!perl -w
sub foo {
    my $x;
    print $x, "\n";
    sub bar { $x = 3 }
}
bar;
foo;

outputs this:

Variable "$x" will not stay shared at - line 4.
3

But this one:

#!perl -w
sub foo {
    my $x;
    print $x, "\n";
    sub bar { sub { $x = 3 }->() }
}
bar;
foo;

outputs this:

Variable "$x" will not stay shared at - line 5.
Variable "$x" is not available at - line 5.
Use of uninitialized value $x in print at - line 4.
<blank line>

Is this discrepancy necessary?  To me ‘Variable "$x" is not available’
makes sense if the outer sub is a closure prototype (CvCLONE &&
!CvCLONED), but if it is a callable sub, I don’t see why this needs to
happen.  And it leads to the discrepancy shown above.

The reason I bring this up is that the very same code paths cause this
(on the sprout/lexsub branch):

$ ./miniperl -lw -e' sub foo { my $x = shift; my sub x { $x } \&x }
print foo->()'
Variable "$x" is not available at -e line 1.
Use of uninitialized value in print at -e line 1.
<blank line>

because the x sub is cloned when foo enters, and $x is still marked stale.

Is it ok to change this?  (Doing so would also allow me to remove the
clonecv op type.  Right now the sprout/lexsub branch creates two ops
[introcv and clonecv] on scope entry for every my sub in that scope.)
-- 

Father Chrysostomos


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