The question is, when does the object get destroyed given this code?
Well, contrary to expectation (well, at least mine), the object does not get destroyed until global destruction! As the following output shows:if (my $object = Foo->new) {} print "after if\n"; package Foo; sub new { my $self = bless {},shift; print "CREATED $self\n"; $self } sub DESTROY { print "DESTROYED $_[0]\n" }
instead of the expected:CREATED Foo=HASH(0xfc65c) after if DESTROYED Foo=HASH(0xfc65c)
It appears that this behaviour is intentional and goes back until at least 5.00504. It is caused by the fact that any lexical inside an if() gets a refcount of 2, rather than of 1.CREATED Foo=HASH(0xfc65c) DESTROYED Foo=HASH(0xfc65c) after if
If this really is a problem for you, then there is the Internals module which allows you to set the refcount of a variable from Perl.
Note that the object now is destroyed at the end of the if(), but that we get a warning at global destruction as a bonus.use Internals qw(SetRefCount); if (my $object = Foo->new) { SetRefCount( $object,1 ) } print "after if\n"; package Foo; sub new { my $self = bless {},shift; print "CREATED $self\n"; $self } sub DESTROY { print "DESTROYED $_[0]\n" } __END__ CREATED Foo=HASH(0xfc65c) DESTROYED Foo=HASH(0xfc65c) after if Attempt to free unreferenced scalar: SV 0xfc65c.
Of course, there is a much simpler method: just add an extra scope!
{ if (my $object = Foo->new) { } } print "after if\n"; package Foo; sub new { my $self = bless {},shift; print "CREATED $self\n"; $self } sub DESTROY { print "DESTROYED $_[0]\n" } __END__ CREATED Foo=HASH(0xfc65c) DESTROYED Foo=HASH(0xfc65c) after if
Hope this maybe helpful for someone someday.
Liz
In reply to Lexicals in if() scope gotcha! by liz
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |