diff options
Diffstat (limited to 'pod')
-rw-r--r-- | pod/perldiag.pod | 51 | ||||
-rw-r--r-- | pod/perlintern.pod | 43 | ||||
-rw-r--r-- | pod/perlref.pod | 20 |
3 files changed, 68 insertions, 46 deletions
diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 603dfc8812..e2728d1798 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -4350,26 +4350,35 @@ instance. This is almost always a typographical error. Note that the earlier variable will still exist until the end of the scope or until all closure referents to it are destroyed. -=item Variable "%s" may be unavailable +=item Variable "%s" is not available -(W closure) An inner (nested) I<anonymous> subroutine is inside a -I<named> subroutine, and outside that is another subroutine; and the -anonymous (innermost) subroutine is referencing a lexical variable -defined in the outermost subroutine. For example: +(W closure) During compilation, an inner named subroutine or eval is +attempting to capture an outer lexical that is not currently available. +This can be happen for one of two reasons. First, the outer lexical may be +declared in an outer anonymous subroutine that has not yet been created. +(Remember that named subs are created at compile time, while anonymous +subs are created at run-time. For example, - sub outermost { my $a; sub middle { sub { $a } } } + sub { my $a; sub f { $a } } -If the anonymous subroutine is called or referenced (directly or -indirectly) from the outermost subroutine, it will share the variable as -you would expect. But if the anonymous subroutine is called or -referenced when the outermost subroutine is not active, it will see the -value of the shared variable as it was before and during the *first* -call to the outermost subroutine, which is probably not what you want. +At the time that f is created, it can't capture the current value of $a, +since the anonymous subroutine hasn't been created yet. Conversely, +the following won't give a warning since the anonymous subroutine has by +now been created and is live: -In these circumstances, it is usually best to make the middle subroutine -anonymous, using the C<sub {}> syntax. Perl has specific support for -shared variables in nested anonymous subroutines; a named subroutine in -between interferes with this feature. + sub { my $a; eval 'sub f { $a }' }->(); + +The second situation is caused by an eval accessing a variable that has +gone out of scope, for example, + + sub f { + my $a; + sub { eval '$a' } + } + f()->(); + +Here, when the '$a' in the eval is being compiled, f() is not currently being +executed, so its $a is not available for capture. =item Variable syntax @@ -4380,22 +4389,18 @@ Perl yourself. =item Variable "%s" will not stay shared (W closure) An inner (nested) I<named> subroutine is referencing a -lexical variable defined in an outer subroutine. +lexical variable defined in an outer named subroutine. -When the inner subroutine is called, it will probably see the value of +When the inner subroutine is called, it will see the value of the outer subroutine's variable 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 variable. In other words, the variable will no longer be shared. -Furthermore, if the outer subroutine is anonymous and references a -lexical variable outside itself, then the outer and inner subroutines -will I<never> share the given variable. - This problem can usually be solved by making the inner subroutine anonymous, using the C<sub {}> syntax. When inner anonymous subs that -reference variables in outer subroutines are called or referenced, they +reference variables in outer subroutines are created, they are automatically rebound to the current values of such variables. =item Version number must be a constant number diff --git a/pod/perlintern.pod b/pod/perlintern.pod index c4bb1d5a01..2ae4a654dd 100644 --- a/pod/perlintern.pod +++ b/pod/perlintern.pod @@ -428,7 +428,8 @@ CV's can have CvPADLIST(cv) set to point to an AV. For these purposes "forms" are a kind-of CV, eval""s are too (except they're not callable at will and are always thrown away after the eval"" is done -executing). +executing). Require'd files are simply evals without any outer lexical +scope. XSUBs don't have CvPADLIST set - dXSTARG fetches values from PL_curpad, but that is really the callers pad (a slot of which is allocated by @@ -474,10 +475,14 @@ stash of the associated global (so that duplicate C<our> delarations in the same package can be detected). SvCUR is sometimes hijacked to store the generation number during compilation. -If SvFAKE is set on the name SV then slot in the frame AVs are -a REFCNT'ed references to a lexical from "outside". In this case, -the name SV does not have a cop_seq range, since it is in scope -throughout. +If SvFAKE is set on the name SV, then that slot in the frame AV is +a REFCNT'ed reference to a lexical from "outside". In this case, +the name SV does not use NVX and IVX to store a cop_seq range, since it is +in scope throughout. Instead IVX stores some flags containing info about +the real lexical (is it declared in an anon, and is it capable of being +instantiated multiple times?), and for fake ANONs, NVX contains the index +within the parent's pad where the lexical's value is stored, to make +cloning quicker. If the 'name' is '&' the corresponding entry in frame AV is a CV representing a possible closure. @@ -538,14 +543,13 @@ Found in file pad.c =item pad_add_name -Create a new name in the current pad at the specified offset. +Create a new name and associated PADMY SV in the current pad; return the +offset. If C<typestash> is valid, the name is for a typed lexical; set the name's stash to that value. If C<ourstash> is valid, it's an our lexical, set the name's GvSTASH to that value -Also, if the name is @.. or %.., create a new array or hash for that slot - If fake, it means we're cloning an existing entry PADOFFSET pad_add_name(char *name, HV* typestash, HV* ourstash, bool clone) @@ -589,12 +593,23 @@ Found in file pad.c =item pad_findlex Find a named lexical anywhere in a chain of nested pads. Add fake entries -in the inner pads if it's found in an outer one. innercv is the CV *inside* -the chain of outer CVs to be searched. If newoff is non-null, this is a -run-time cloning: don't add fake entries, just find the lexical and add a -ref to it at newoff in the current pad. - - PADOFFSET pad_findlex(char* name, PADOFFSET newoff, CV* innercv) +in the inner pads if it's found in an outer one. + +Returns the offset in the bottom pad of the lex or the fake lex. +cv is the CV in which to start the search, and seq is the current cop_seq +to match against. If warn is true, print appropriate warnings. The out_* +vars return values, and so are pointers to where the returned values +should be stored. out_capture, if non-null, requests that the innermost +instance of the lexical is captured; out_name_sv is set to the innermost +matched namesv or fake namesv; out_flags returns the flags normally +associated with the IVX field of a fake namesv. + +Note that pad_findlex() is recursive; it recurses up the chain of CVs, +then comes back down, adding fake entries as it goes. It has to be this way +because fake namesvs in anon protoypes have to store in NVX the index into +the parent pad. + + PADOFFSET pad_findlex(char *name, CV* cv, U32 seq, int warn, SV** out_capture, SV** out_name_sv, int *out_flags) =for hackers Found in file pad.c diff --git a/pod/perlref.pod b/pod/perlref.pod index 7f9b638fad..07b2f8272f 100644 --- a/pod/perlref.pod +++ b/pod/perlref.pod @@ -542,10 +542,10 @@ remains available. =head2 Function Templates -As explained above, a closure is an anonymous function with access to the -lexical variables visible when that function was compiled. It retains -access to those variables even though it doesn't get run until later, -such as in a signal handler or a Tk callback. +As explained above, an anonymous function with access to the lexical +variables visible when that function was compiled, creates a closure. It +retains access to those variables even though it doesn't get run until +later, such as in a signal handler or a Tk callback. Using a closure as a function template allows us to generate many functions that act similarly. Suppose you wanted functions named after the colors @@ -585,11 +585,13 @@ to occur during compilation. Access to lexicals that change over type--like those in the C<for> loop above--only works with closures, not general subroutines. In the general case, then, named subroutines do not nest properly, although anonymous -ones do. If you are accustomed to using nested subroutines in other -programming languages with their own private variables, you'll have to -work at it a bit in Perl. The intuitive coding of this type of thing -incurs mysterious warnings about ``will not stay shared''. For example, -this won't work: +ones do. Thus is because named subroutines are created (and capture any +outer lexicals) only once at compile time, whereas anonymous subroutines +get to capture each time you execute the 'sub' operator. If you are +accustomed to using nested subroutines in other programming languages with +their own private variables, you'll have to work at it a bit in Perl. The +intuitive coding of this type of thing incurs mysterious warnings about +``will not stay shared''. For example, this won't work: sub outer { my $x = $_[0] + 35; |