develooper Front page | perl.perl5.porters | Postings from May 2012

Re: [perl #94682] Wrong warning 'Variable "$_" is not available' inclosure

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
May 10, 2012 06:27
Subject:
Re: [perl #94682] Wrong warning 'Variable "$_" is not available' inclosure
Message ID:
20120510132705.GR9069@plum.flirble.org
On Tue, Sep 06, 2011 at 12:29:00PM +0100, Dave Mitchell wrote:

> There is a second issue that is brought up by the original bug report,
> and that is that $a =~ /foo/ closes over any outer lexical $_, even though
> it doesn't use $_. This is because when /foo/ is compiled, it initially
> assumes that it wants to use $_ and so closes over it (if there's a lexical
> version in scope); only later does it see the =~ bind operator, and
> undo that assumption (by setting OPf_STACKED). By then the closure
> has already been set up (a FAKE entry in the pad).
> 
> I don't see a simple way to fix that.

Meaning that the third section of this code is buggy?

$ cat ../test/94682.pl
#!/usr/bin/perl -w

sub DESTROY {
    print "DESTROY for $_[0]\n";
}

sub should_close {
    my $_ = shift;
    return sub {
        print "I'm really in a closure with $_\n";
    }
}

sub should_not_close {
    my $_ = shift;
    return sub {
        print "I'm not a closure\n";
    }
}

sub buggy {
    my $_ = shift;
    return sub {
        my $m = "I'm not to be a closure\n";
        $m =~ s/not/not meant/;
        print $m;
    }
}

print "Should close\n";
my $s = should_close(bless []);
print "(object should live)\n";
$s->();
undef $s;
print "\n";

print "Should not close\n";
$s = should_not_close(bless []);
print "(object should be gone)\n";
$s->();
undef $s;
print "\n";

print "Should not close either\n";
$s = buggy(bless []);
print "(object should be gone)\n";
$s->();
undef $s;

__END__
$ ./perl -Ilib ../test/94682.pl 
Should close
(object should live)
I'm really in a closure with main=ARRAY(0x100802eb8)
DESTROY for main=ARRAY(0x100802eb8)

Should not close
DESTROY for main=ARRAY(0x1008114a8)
(object should be gone)
I'm not a closure

Should not close either
(object should be gone)
I'm not meant to be a closure
DESTROY for main=ARRAY(0x1008114c0)


In that the sub buggy() should not return a closure, hence the third
paragraph of output should be the same as the second, not the first, as
currently is?

(and this should become a TODO test somewhere?)

Nicholas Clark

Thread Previous | Thread Next


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