This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Close over stale vars in active subs
authorFather Chrysostomos <sprout@cpan.org>
Sat, 4 Aug 2012 21:42:47 +0000 (14:42 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 4 Aug 2012 22:56:22 +0000 (15:56 -0700)
commitcae5dbbe30ba4a96ff5e570be0d90779f06fee71
tree5cf09fd30ac0981e861f9dda87ba20e486d67fbb
parent3207fc6be298e308e8094e866ca339ba7e9a2790
Close over stale vars in active subs

\$x and sub { $x }->() should never produce different values.  But
this used to be possible because sub cloning (which happens with
sub{...}) was written to avoid closing over variables that are not
active.  Not closing over inactive variables makes sense in cases like
this (because the variable doesn’t really exist yet):

sub {
    my $x;
    sub foo {
        $x
    }
}
foo;

but the logic breaks down in cases like this (which was printing 3
only on the first print):

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

If bar can see a scalar named $x (even if it is questionable),
sub { $x }->() should jolly well see the same scalar as the immedi-
ately enclosing sub.

The only case where a run-time cloning of a CV should refuse to close
over the same scalar that the outer sub sees is when the outer sub is
not running.  That only happens with formats:

sub f {
    my $x;
    format =
@
$x
.
}
write STDOUT;

As of this commit, it does only happen with formats.

The actual cases of subs refusing to close over stale variables in
active parents have changed twice since 5.10.0.  See the comments in
the tests.
pad.c
t/op/closure.t