diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-06-30 20:26:34 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-07-25 23:48:02 -0700 |
commit | 137da2b05b4b7628115049f343163bdaf2c30dbb (patch) | |
tree | f67f94858229947447c68a9676d49af49c593d4b /t | |
parent | d2440203227a535b62a2078d898d0bd993ceac78 (diff) | |
download | perl-137da2b05b4b7628115049f343163bdaf2c30dbb.tar.gz |
[perl #79908] Stop sub inlining from breaking closures
When a closure closes over a variable, it references the variable
itself, as opposed to taking a snapshot of its value.
This was broken by the constant optimisation added for
constant.pm’s sake:
{
my $x;
sub () { $x }; # takes a snapshot of the current value of $x
}
constant.pm no longer uses that mechanism, except on older perls, so
we can remove this hack, causing code like this this to start work-
ing again:
BEGIN{
my $x = 5;
*foo = sub(){$x};
$x = 6
}
print foo; # now prints 6, not 5
Diffstat (limited to 't')
-rw-r--r-- | t/op/sub.t | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/t/op/sub.t b/t/op/sub.t index 3546880157..56bbaaec66 100644 --- a/t/op/sub.t +++ b/t/op/sub.t @@ -6,7 +6,7 @@ BEGIN { require './test.pl'; } -plan( tests => 23 ); +plan( tests => 26 ); sub empty_sub {} @@ -142,3 +142,22 @@ eval { ${\not_constantm}++ }; is $@, "", 'my sub (){42} returns a mutable value'; eval { ${\not_constantmr}++ }; is $@, "", 'my sub (){ return 42 } returns a mutable value'; + +# [perl #79908] +{ + my $x = 5; + *_79908 = sub (){$x}; + $x = 7; + is eval "_79908", 7, 'sub(){$x} does not break closures'; + isnt eval '\_79908', \$x, 'sub(){$x} returns a copy'; + + # Test another thing that was broken by $x inlinement + my $y; + no warnings 'once'; + local *time = sub():method{$y}; + my $w; + local $SIG{__WARN__} = sub { $w .= shift }; + eval "()=time"; + is $w, undef, + '*keyword = sub():method{$y} does not cause ambiguity warnings'; +} |