The following will demonstrate an approach to define a &SUPEREND::DESTROY which is run after all other global DESTROY()s happend.
use strict;
use warnings;
package Blubb;
sub new {
my $this = bless {a=>42};
$this->{circular} = $this;
}
sub DESTROY {
warn "DESTROY ". __PACKAGE__;
}
package SUPEREND;
no warnings 'redefine';
my $orig_destroy= \&Blubb::DESTROY;
my $persist = bless { count=>0};
*Blubb::DESTROY= sub {
$orig_destroy->(@_);
warn "Mini END";
$persist->{count}++;
};
sub DESTROY {
warn "DESTROY after $_[0]->{count} destroys ". __PACKAGE__;
}
package MAIN;
my $b = Blubb->new;
my $c = Blubb->new;
my $d = Blubb->new;
DESTROY Blubb at c:/tmp/pm/destruct_end.pl line 12 during global destr
+uction.
Mini END at c:/tmp/pm/destruct_end.pl line 25 during global destructio
+n.
DESTROY Blubb at c:/tmp/pm/destruct_end.pl line 12 during global destr
+uction.
Mini END at c:/tmp/pm/destruct_end.pl line 25 during global destructio
+n.
DESTROY Blubb at c:/tmp/pm/destruct_end.pl line 12 during global destr
+uction.
Mini END at c:/tmp/pm/destruct_end.pl line 25 during global destructio
+n.
DESTROY after 3 destroys SUPEREND at c:/tmp/pm/destruct_end.pl line 33
+ during global destruction.
Please note, that this can be extended to be a generic solution, because SUPEREND could parse all packages available and monkeypatch all DESTROYs there (if existent)
Since $persist is referenced it's DESTROY will be run last.
For syntactic sugar one could also make SUPEREND export a function SUPEREND(&) accepting a codeblock which is run by the DESTROY of $persist.
|