Re: Ignorant wumpus? Or scoping problem?
by Dave Mitchell other posts by this author
Nov 26 2003 10:38AM messages near this date
Ignorant wumpus? Or scoping problem?
|
[patch pod/perlref.pod] (was Re: Ignorant wumpus? Or scoping problem?)
On Tue, Nov 25, 2003 at 02:10:00PM -0800, Glenn Linderman wrote:
> 1) Do the initial "use strict" and "use warnings" apply to the eval'd
> code
Yes, they are lexically scoped, eg
$ perl -e 'use strict; eval q{$x=1}; print $@'
Global symbol "$x" requires explicit package name at (eval 1) line 1.
> 2) The variables of interest are all lexicals in the scope of the
> closure where function foo is defined... $scaler, @array, and %hash.
> The functions, with strict and warnings enabled, seem to compile fine.
> But when function eval_printall runs, the variables seem to all be
> undefined
Closures work at follows: when a sub is created, it captures the currrent
instances of any lexical variables that are referred to inside the sub,
but which are delcared outside that sub. The use of eval often delays this
capturing, so that the required lexicals are no longer available.
eg this simple 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 disacards 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 actually 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=
The moral of this tale is to be careful with evals. They often do funny
things because the compiler can't know in advance what the eval might
contain.
--
"I do not resent critisism, even when, for the sake of emphasis,
it parts for the time with reality".
-- Winston Churchill, House of Commons, 22nd Jan 1941.
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
|