Objects that have gone out of scope and not referenced elsewere are destroyed when exiting
the routine or module that contains the said scope.
This is done by the opcode leave as you can convince yourself by examining the following program and its trace.
program:
package A;
sub DESTROY { print "destroy\n"; }
sub new { bless {}, A }
package main;
my ($a, $o) = ( 1 );
if ( $a ) {
my $a = A->new;
print "scope left\n";
}
trace:
./perl -Dt /tmp/test
(/tmp/test:3) null
(/tmp/test:3) const(PV("destroy\12"\0))
(/tmp/test:3) stringify
(/tmp/test:11) null
(/tmp/test:11) const(PV("scope left\12"\0))
(/tmp/test:11) stringify
EXECUTING...
(/tmp/test:0) enter
(/tmp/test:0) nextstate
(/tmp/test:8) pushmark
(/tmp/test:8) const(IV(1))
(/tmp/test:8) pushmark
(/tmp/test:8) padsv($a)
(/tmp/test:8) padsv($o)
(/tmp/test:8) aassign
(/tmp/test:8) nextstate
(/tmp/test:9) padsv($a)
(/tmp/test:9) and
(/tmp/test:9) enter
(/tmp/test:9) nextstate
(/tmp/test:10) pushmark
(/tmp/test:10) const(PV("A"\0))
(/tmp/test:10) method_named
(/tmp/test:10) entersub
(/tmp/test:10) nextstate
(/tmp/test:4) pushmark
(/tmp/test:4) anonhash
(/tmp/test:4) srefgen
(/tmp/test:4) const(PV("A"\0))
(/tmp/test:4) bless
(/tmp/test:4) leavesub
(/tmp/test:10) padsv($a)
(/tmp/test:10) sassign
(/tmp/test:10) nextstate
(/tmp/test:11) pushmark
(/tmp/test:11) const(PV("scope left\12"\0))
(/tmp/test:11) print
scope left
(/tmp/test:11) leave # this "leave" triggers the DESTROY
+ call
(/tmp/test:9) nextstate
(/tmp/test:3) pushmark
(/tmp/test:3) const(PV("destroy\12"\0))
(/tmp/test:3) print
destroy
(/tmp/test:3) leavesub
(/tmp/test:9) leave
-- stefp