[patch pod/perlref.pod] (was Re: Ignorant wumpus? Or scoping problem?)
by Stas Bekman other posts by this author
Nov 28 2003 9:10AM messages near this date
Re: Ignorant wumpus? Or scoping problem?
|
Re: [patch pod/perlref.pod] (was Re: Ignorant wumpus? Or scoping problem?)
Dave, I took the liberty to add your explanation almost verbatim to perlref.
You may want to polish it later, but I think it's pretty important to put that
info in. And your explanation and the example were pretty clear to me. I
mainly stressed that it's the string form of eval (it doesn't apply to eval {} )
Also I hope that I put it in the right place in perlref, as it explains
closures in two places.
Here is the patch:
--- pod/perlref.pod.orig 2003-11-28 00:58:48.000000000 -0800
+++ pod/perlref.pod 2003-11-28 01:06:17.000000000 -0800
@@ -195,6 +195,51 @@
continue to work as they have always worked. Closure is not something
that most Perl programmers need trouble themselves about to begin with.
+Note that lexical variables used inside the string form of C<eval()>
+might not create a closure if not references elsewhere in the
+subroutine. This is because only when the string is eval'ed at
+run-time, can perl see that a variable is references from within the
+the eval'ed string. At compile time it's not known whether there is a
+lexical variable inside the string or not. For example:
+
+ {
+ my $x = 1;
+ sub f1 { print "f1: x=$x\n" }
+ sub f2 { eval 'print "f2: x=$x\n"' }
+ }
+
+ f1;
+ f2;
+
+produces the following output:
+
+ f1: x=1
+ Use of uninitialized value in concatenation (.) or string at (eval 1) line 1.
+ f2: x=
+
+What happens here is that when f1 is compiled, the compiler notices
+that the sub f1 makes mention of the outer lexical $x, so f1 gets its
+own private reference to that variable. When f2 is compiled, it has no
+such mention of $x, so it doesn't also capture $x.
+
+After the { } block is exited, the interpreter discards the current
+(and only) instance of $x. When f1 is later called, it still has its
+private copy of $x, and so can print out its value. When the eval is
+compiled via f2, f2 hasn't got a private copy of $x, so the eval tries
+to grab the value of the 'real' $x, which is now undef.
+
+In the current development version of perl, you get a warning when
+this happens:
+
+ f1: x=1
+ Variable "$x" is not available at (eval 1) line 1.
+ Use of uninitialized value in concatenation (.) or string at (eval 1) line 1.
+ f2: x=
+
+Therefore be careful when wanting to create a closure and using the
+string form of eval.
+
+
=item 5.
References are often returned by special subroutines called constructors.
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:stas@[...].org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
Thread:
Glenn Linderman
Dave Mitchell
Stas Bekman
Brad Baxter
Stas Bekman
Dave Mitchell
Stas Bekman
Glenn Linderman
Dave Mitchell
Glenn Linderman
Dave Mitchell
Glenn Linderman
Brad Baxter
Brad Baxter
Glenn Linderman
Dave Mitchell
Rafael Garcia-Suarez
Glenn Linderman
Stas Bekman
Glenn Linderman
Alan Burlison
|