prefer polymorphism on existing destructor over custom destructor method

This commit is contained in:
Robert Stone 2013-11-14 07:29:28 -08:00
commit e0789366e7
3 changed files with 35 additions and 9 deletions

View file

@ -3231,6 +3231,30 @@ destroyed together. Destroying one without destroying the other will
likely cause your program to segfault.
</p>
<p>
Also note that due to the proxy implementation, the <tt>DESTROY()</tt>
method on directors can be called for several reasons, many of which
have little to do with the teardown of an object instance. To help
disambiguate this, a second argument is added to the <tt>DESTROY()</tt>
call when a C++ director object is being released. So, to avoid running
your clean-up code when an object is not really going away, or after it
has already been reclaimed, it is suggested that custom destructors in
Perl subclasses looks something like:
</p>
<div class="targetlang">
<pre>
sub DESTROY {
my($self, $final) = @_;
if($final) {
# real teardown code
}
shift-&gt;SUPER::DESTROY(@_);
}
</pre>
</div>
<H3><a name="Perl5_nn51"></a>31.11.4 Exception unrolling</H3>

View file

@ -7,8 +7,9 @@ require_ok('director_finalizer');
{
package MyFoo;
use base 'director_finalizer::Foo';
sub DIRECTOR_DESTROY { my($self) = @_;
$self->orStatus(2);
sub DESTROY { my($self, $final) = @_;
$self->orStatus(2) if $final;
shift->SUPER::DESTROY(@_);
}
}

View file

@ -1529,11 +1529,11 @@ public:
Delete(get_attr);
Printv(pm, "sub FETCH {\n", tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4,
"if (not $self->can(\"$member_func\")) {\n", tab4, tab4, "my $h = ", cmodule, "::", mrename, "($self);\n", tab4, tab4,
"return $h->{$field} if $h;\n", tab4, "}\n", tab4, "return $self->$member_func;\n", "}\n", "\n", "sub STORE {\n", tab4,
"my ($self,$field,$newval) = @_;\n", tab4, "my $member_func = \"swig_${field}_set\";\n", tab4,
"if (not $self->can(\"$member_func\")) {\n", tab4, tab4, "my $h = ", cmodule, "::", mrename, "($self);\n", tab4, tab4,
"return $h->{$field} = $newval if $h;\n", tab4, "}\n", tab4, "return $self->$member_func($newval);\n", "}\n", NIL);
"if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename, "($self);\n", tab8, "return $h->{$field} if $h;\n",
tab4, "}\n", tab4, "return $self->$member_func;\n", "}\n", "\n", "sub STORE {\n", tab4, "my ($self,$field,$newval) = @_;\n", tab4,
"my $member_func = \"swig_${field}_set\";\n", tab4, "if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename,
"($self);\n", tab8, "return $h->{$field} = $newval if $h;\n", tab4, "}\n", tab4, "return $self->$member_func($newval);\n", "}\n", NIL);
Delete(mrename);
}
}
@ -2493,8 +2493,9 @@ public:
String *mangle = SwigType_manglestr(ptype);
Printv(body, tab4, "dSP;\n", tab4, "SV *self = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE", mangle, ", SWIG_SHADOW);\n", tab4, "\n", tab4,
"sv_bless(self, gv_stashpv(swig_get_class(), 0));\n", tab4, "ENTER;\n", tab4, "SAVETMPS;\n", tab4, "PUSHMARK(SP);\n", tab4, "XPUSHs(self);\n",
tab4, "PUTBACK;\n", tab4, "call_method(\"DIRECTOR_DESTROY\", G_EVAL | G_VOID);\n", tab4, "FREETMPS;\n", tab4, "LEAVE;\n", NIL);
"sv_bless(self, gv_stashpv(swig_get_class(), 0));\n", tab4, "ENTER;\n", tab4, "SAVETMPS;\n", tab4, "PUSHMARK(SP);\n", tab4,
"XPUSHs(self);\n", tab4, "XPUSHs(&PL_sv_yes);\n", tab4, "PUTBACK;\n", tab4, "call_method(\"DESTROY\", G_EVAL | G_VOID);\n", tab4,
"FREETMPS;\n", tab4, "LEAVE;\n", NIL);
Delete(mangle);
Delete(ptype);