Deprecating the modifyable variables in constants by 5.32.
authorAbigail <abigail@abigail.be>
Sat, 14 Jan 2017 17:25:48 +0000 (18:25 +0100)
committerAbigail <abigail@abigail.be>
Mon, 16 Jan 2017 18:18:16 +0000 (19:18 +0100)
It was already deprecated, but we're now adding a version number.

pad.c
pod/perldeprecation.pod
pod/perldiag.pod
t/op/const-optree.t

diff --git a/pad.c b/pad.c
index 6d2d008..5bbb07a 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -2159,7 +2159,8 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned,
                                         "Constants from lexical "
                                         "variables potentially "
                                         "modified elsewhere are "
-                                        "deprecated");
+                                        "deprecated. This will not "
+                                         "be allowed in Perl 5.32");
                        /* We *copy* the lexical variable, and donate the
                           copy to newCONSTSUB.  Yes, this is ugly, and
                           should be killed.  We need to do this for the
index 3cbeffc..3ef41b7 100644 (file)
@@ -14,6 +14,42 @@ features are available.
 The deprecated features will be grouped by the version of Perl in
 which they will be removed.
 
+=head2 Perl 5.32
+
+=head3 Constants from lexical variables potentially modified elsewhere
+
+You wrote something like
+
+    my $var;
+    $sub = sub () { $var };
+
+but $var is referenced elsewhere and could be modified after the C<sub>
+expression is evaluated.  Either it is explicitly modified elsewhere
+(C<$var = 3>) or it is passed to a subroutine or to an operator like
+C<printf> or C<map>, which may or may not modify the variable.
+
+Traditionally, Perl has captured the value of the variable at that
+point and turned the subroutine into a constant eligible for inlining.
+In those cases where the variable can be modified elsewhere, this
+breaks the behavior of closures, in which the subroutine captures
+the variable itself, rather than its value, so future changes to the
+variable are reflected in the subroutine's return value.
+
+If you intended for the subroutine to be eligible for inlining, then
+make sure the variable is not referenced elsewhere, possibly by
+copying it:
+
+    my $var2 = $var;
+    $sub = sub () { $var2 };
+
+If you do want this subroutine to be a closure that reflects future
+changes to the variable that it closes over, add an explicit C<return>:
+
+    my $var;
+    $sub = sub () { return $var };
+
+This usage has been deprecated, and will no longer be allowed in Perl 5.32.
+
 =head2 Perl 5.30
 
 =head3 C<< File::Glob::glob() >> will disappear
index 69812b2..4511dac 100644 (file)
@@ -1794,7 +1794,7 @@ usually indicates a syntax error in dereferencing the constant value.
 See L<perlsub/"Constant Functions"> and L<constant>.
 
 =item Constants from lexical variables potentially modified elsewhere are
-deprecated
+deprecated. This will not be allowed in Perl 5.32
 
 (D deprecated) You wrote something like
 
@@ -1813,8 +1813,8 @@ breaks the behavior of closures, in which the subroutine captures
 the variable itself, rather than its value, so future changes to the
 variable are reflected in the subroutine's return value.
 
-This usage is deprecated, because the behavior is likely to change
-in a future version of Perl.
+This usage is deprecated, and will no longer be allowed in Perl 5.32,
+making it possible to change the behavior in the future.
 
 If you intended for the subroutine to be eligible for inlining, then
 make sure the variable is not referenced elsewhere, possibly by
index b378d4a..4d897d2 100644 (file)
@@ -432,7 +432,8 @@ for \%_ (@tests) {
     if (exists $_{deprecated}) {
         if ($_{deprecated}) {
             like $w, qr/^Constants from lexical variables potentially (?x:
-                       )modified elsewhere are deprecated at /,
+                       )modified elsewhere are deprecated\. This will (?x:
+                       )not be allowed in Perl 5\.32 at /,
                 "$nickname is deprecated";
         }
         else {