-
Notifications
You must be signed in to change notification settings - Fork 19
Destructors
Please see the main page of the repo for the actual RFC. As it states there:
Anything in the Wiki should be considered "rough drafts."
Click here to provide feedback.
To better understand this document, you should read Class Phases.
Just as we have constructors, we also need destructors. These are special methods called during object destruction to ensure that everything that needs to be cleaned up/finalized, is cleaned up/finalized.
Core Perl has an issue here:
#!/usr/bin/env perl
use Less::Boilerplate; # personal version of Modern::Perl
package Parent {
sub new { bless {} => shift }
sub inherited { say "Inherited" }
sub DESTROY { say "Parent" }
}
package Child {
our @ISA = 'Parent';
sub new { bless {} => shift }
sub DESTROY { say "Child" }
}
{
my $thing = Child->new;
$thing->inherited;
}
say "Done";
Running that prints:
Inherited
Child
Done
Note that Parent
is not printed because the parent destructor is not called.
Thus, you need to call $self->next::method
at the end of every DESTROY
.
Moose has sane object destruction via
DEMOLISH,
but Corinna ain't Moose. Moose has BUILD
and DEMOLISH
for
construction/destruction, so Corinna has CONSTRUCT
and DESTRUCT
for
its object construction/destruction.
Most of the time you won't need to add behavior to the DESTRUCT
phase, but
if you do:
DESTRUCT ($destruction) {
if ($destruction->is_global) {
...
}
else {
...
}
}
The DESTRUCT
phase receives a Cor::Destruction
object which currently has
one method, is_global
:
class Cor::Destruction {
has $is_global :reader :new :isa(Bool);
}
The Cor::Destruction
object is not created unless there is a target
DESTRUCT
phaser to pass it to. Thus, Cor::Destruction
will never be passed
to itself, avoiding an infinite loop.
In core Perl, it's often hard to know exactly when data gets destroyed in object destruction. For Cor, we suggest a deterministic order:
- Children destroyed before parents
- Instance data before class data
- Slots destroyed in reverse order of declaration
With the above, we can reason about exactly when and how object destruction occurs.
Further, the order of destruction has been choses to ensure that dependencies get destroyed after the things that depend on them. Thus, declare you database handle at the top of your attribute list and you'll always be guaranteed the handle is there.
Corinna—Bringing Modern OO to Perl