develooper Front page | perl.perl5.porters | Postings from October 2003

Re: [perl #24296] scalars and hashes sometimes not available in quoted evals in END blocks

From:
Dave Mitchell
Date:
October 28, 2003 02:30
Subject:
Re: [perl #24296] scalars and hashes sometimes not available in quoted evals in END blocks
Message ID:
20031028103004.GA19491@fdgroup.com
On Sun, Oct 26, 2003 at 05:39:37AM -0000, David Dyck wrote:
> # New Ticket Created by  David Dyck 
> # Please include the string:  [perl #24296]
> # in the subject line of all future correspondence about this issue. 
> # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=24296 >
> 
> 
> 
> This is a bug report for perl from david.dyck@fluke.com,
> generated with the help of perlbug 1.34 running under perl v5.9.0.
> 
> 
> -----------------------------------------------------------------
> [Please enter your report here]
> 
> I had a scripting tool that used perl, and recently
> discovered that when I eval a single-quoted string q{}
> called from an END block the variable is not accessable,
> even though it still has a value.
> 
> Please notice how the scalar $my_scalar is not "available"
> for a short while when called from the END block, but
> it should be, as it still exists and has a value.
> This case doesn't seem to be covered in perldiag's documentation
> for this warning.
>  (removing the q allows the code to appear to work, but in
>   my case, the string I want to eval is not known until the
>   END block is executed, hence the single-quote string)
> 
> #!/usr/local/bin/perl -w
> 
> $|=1;
> use strict;
> 
> my $my_scalar = "my_scalar";
> 
> sub showvars
> {
>     eval q{ print "my_scalar=$my_scalar\n" ;  };
>     warn "$@" if length $@;
> }
> 
> END {
>     print "END\n";
>     showvars;
>     print "my_scalar=$my_scalar\n";
> }
> 
> showvars;
> 
> __END__
> 
> my_scalar=my_scalar
> END
> Variable "$my_scalar" is not available at (eval 2) line 1.
> Use of uninitialized value in concatenation (.) or string at (eval 2) line 1.
> my_scalar=
> my_scalar=my_scalar

This is the correct behaviour. The showvars sub is *not* a closure (it
doesn't have a compile-time mention of the outer lexical), while the END
sub *is a closure. Thus at compile time the END sub captures the first
(and only) instance of $my_scalar. By the time END is called, the pad for
the main code block has already been freed, so the var isn't available.
But END has its own private reference to it, so the END sub can still
access it.

You can see a similar affect in this piece of code (not involving END):

    {
	my $x = 55;
	sub f1 { print "f1: x=$x\n" }
	sub f2 { print "f2: x=", eval '$x', "\n" }
    }

    f1;
    f2;

    __END__

    f1: x=55
    Variable "$x" is not available at (eval 1) line 2.
    Use of uninitialized value in print at /tmp/p line 7.
    f2: x=

Dave.

-- 
"Do not dabble in paradox, Edward, it puts you in danger of fortuitous
wit." Lady Croom - Arcadia



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About