summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2014-11-24 00:33:35 -0800
committerFather Chrysostomos <sprout@cpan.org>2014-11-30 11:48:38 -0800
commit2a9203e94b669f45c3d0b2161702767b6a8ac237 (patch)
tree56c228dc8f79bb3cb5d58db02ef08d8c50666431
parent6ccbd5ffeda04f22f5ad352866c49d46b8ae84ac (diff)
downloadperl-2a9203e94b669f45c3d0b2161702767b6a8ac237.tar.gz
‘Subroutine (not var) "&x" will not stay shared’
Another ‘variable’ warning about lexical subs that I missed.
-rw-r--r--pad.c5
-rw-r--r--pod/perldiag.pod19
-rw-r--r--t/op/lexsub.t10
3 files changed, 32 insertions, 2 deletions
diff --git a/pad.c b/pad.c
index e7392aba4b..6707542d3f 100644
--- a/pad.c
+++ b/pad.c
@@ -1233,8 +1233,11 @@ S_pad_findlex(pTHX_ const char *namepv, STRLEN namelen, U32 flags, const CV* cv,
&& !PadnameIsSTATE(name_p[offset])
&& warn && ckWARN(WARN_CLOSURE)) {
newwarn = 0;
+ /* diag_listed_as: Variable "%s" will not stay
+ shared */
Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
- "Variable \"%"UTF8f"\" will not stay shared",
+ "%se \"%"UTF8f"\" will not stay shared",
+ *namepv == '&' ? "Subroutin" : "Variabl",
UTF8fARG(1, namelen, namepv));
}
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index a369a70540..f9a56fa3a1 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -5438,6 +5438,25 @@ the previous instance. This is almost always a typographical error.
Note that the earlier subroutine will still exist until the end of
the scope or until all closure references to it are destroyed.
+=item Subroutine "%s" will not stay shared
+
+(W closure) An inner (nested) I<named> subroutine is referencing a "my"
+subroutine defined in an outer named subroutine.
+
+When the inner subroutine is called, it will see the value of the outer
+subroutine's lexical subroutine as it was before and during the *first*
+call to the outer subroutine; in this case, after the first call to the
+outer subroutine is complete, the inner and outer subroutines will no
+longer share a common value for the lexical subroutine. In other words,
+it will no longer be shared. This will especially make a difference
+if the lexical subroutines accesses lexical variables declared in its
+surrounding scope.
+
+This problem can usually be solved by making the inner subroutine
+anonymous, using the C<sub {}> syntax. When inner anonymous subs that
+reference lexical subroutines in outer subroutines are created, they
+are automatically rebound to the current values of such lexical subs.
+
=item Subroutine %s redefined
(W redefine) You redefined a subroutine. To suppress this warning, say
diff --git a/t/op/lexsub.t b/t/op/lexsub.t
index 32f8bc7eac..f43285f115 100644
--- a/t/op/lexsub.t
+++ b/t/op/lexsub.t
@@ -7,7 +7,7 @@ BEGIN {
*bar::is = *is;
*bar::like = *like;
}
-plan 146;
+plan 147;
# -------------------- Errors with feature disabled -------------------- #
@@ -807,6 +807,14 @@ is runperl(switches => ['-lXMfeature=:all'],
like $@, qr/^Undefined subroutine &φου called at /,
'my sub with utf8 name';
}
+{
+ my $w;
+ local $SIG{__WARN__} = sub { $w = shift };
+ use warnings 'closure';
+ eval 'sub stayshared { my sub x; sub notstayshared { x } } 1' or die;
+ like $w, qr/^Subroutine "&x" will not stay shared at /,
+ 'Subroutine will not stay shared';
+}
# -------------------- Interactions (and misc tests) -------------------- #