ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> perl5-porters
perl5-porters
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

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved