ferrency has asked for the wisdom of the Perl Monks concerning the following question:
I just came across a behavior in Perl (5.8.0) which I did not predict. When calling a function inside a foreach statement's LIST, any lexicals declared inside that function were not destroyed when I expected them to be destroyed.
Here is a minimal example which demonstrates what I mean:
This warns no lock 2 because the lexical $F inside fn() is not destroyed until after the foreach loop is finished.#!/usr/local/bin/perl use Fcntl qw(LOCK_EX LOCK_UN LOCK_NB); # This opens a file in a lexcially scoped file handle, and flocks it. # It will close and unlock when that variable goes out of scope. sub fn { my $fn = "FOO"; open my $F, ">$fn"; flock($F, LOCK_EX) or die "no lock"; return $fn; } # In this case, for some reason $F above isn't destroyed until after # the for loop completes. for my $fn (fn()) { open my $G, $fn; flock($G, LOCK_EX|LOCK_NB) or warn "no lock 2"; }
Does anyone have a good explanation for why this makes sense? A more complete example is below...
In this example, it warns no lock 3 and no lock 4, but the rest of the cases destroy fn()'s lexical variables when I'd expect.
Thanks for any light you can shed on this one!
And, to demonstrate that it's not limited to the case of implicitly closing filehandles:#!/usr/local/bin/perl use Fcntl qw(LOCK_EX LOCK_UN LOCK_NB); # This opens a file in a lexcially scoped file handle, and flocks it. # It will close and unlock when that variable goes out of scope. sub fn { my $fn = "FOO"; open my $F, ">$fn"; flock($F, LOCK_EX) or die "no lock"; return $fn; } my $fn = fn(); for ($fn) { open my $G, $fn; flock($G, LOCK_EX|LOCK_NB) or warn "no lock 2"; } # In this case, for some reason $F above isn't destroyed until after # the for loop completes. for my $fn (fn()) { open my $G, $fn; flock($G, LOCK_EX|LOCK_NB) or warn "no lock 3"; } for (my $fn = fn()) { open my $G, $fn; flock($G, LOCK_EX|LOCK_NB) or warn "no lock 4"; } while (my $fn = fn()) { open my $G, $fn; flock($G, LOCK_EX|LOCK_NB) or warn "no lock 5"; last; } open my $G, $fn; flock($G, LOCK_EX|LOCK_NB) or warn "no lock 6";
This prints I fot FOO before DESTROYING FOO.sub FOO::DESTROY {print "DESTROYING FOO\n"} sub fn { my $fn = "FOO"; my $x = bless \$fn, "FOO"; return $x; } # In this case, for some reason $F above isn't destroyed until after # the for loop completes. for my $fn (fn()) { print "I got $fn\n"; }
Alan
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Unpredicted late destruction
by Abigail-II (Bishop) on Nov 05, 2003 at 17:06 UTC | |
by broquaint (Abbot) on Nov 05, 2003 at 17:55 UTC | |
by ferrency (Deacon) on Nov 12, 2003 at 15:36 UTC | |
by ferrency (Deacon) on Nov 05, 2003 at 17:51 UTC | |
Re: Unpredicted late destruction
by broquaint (Abbot) on Nov 05, 2003 at 16:59 UTC |
Back to
Seekers of Perl Wisdom