Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Why is the base class's destructor not called?

by lifang11 (Initiate)
on Jan 21, 2014 at 06:38 UTC ( #1071432=perlquestion: print w/ replies, xml ) Need Help??
lifang11 has asked for the wisdom of the Perl Monks concerning the following question:

A.pm
#!/usr/bin/perl package A; use warnings; use strict; sub new { my $object = shift; my $class = ref($object)||$object; my $self = {}; bless($self,$class); return $self; } sub DESTROY { print("DESTROY in A","\n"); } sub hello { print("hello in A\n"); } return 1;
====================================== B.pm
#!/usr/bin/perl package B; use warnings; use strict; use A; our @ISA=qw(A); sub new { my $object = shift; my $class = ref($object)||$object; my $self = $class->SUPER::new(); bless($self,$class); return $self; } sub DESTROY { print("DESTROY in B","\n"); } sub hello { my $self = shift; $self->SUPER::hello(); print("hello in B\n"); } return 1;
============================== main.pl
#!/usr/bin/perl use warnings; use strict; use FindBin; use lib "$FindBin::Bin/class"; use B; my $b = new B(); $b->hello();
===================================== output:
hello in A hello in B DESTROY in B
Why is the base class's destructor not called?

Comment on Why is the base class's destructor not called?
Select or Download Code
Re: Why is the base class's destructor not called?
by BrowserUk (Pope) on Jan 21, 2014 at 06:42 UTC

    Just as you had to call SUPER::new to invoke A's constructor, you'd need to do the same thing for A's destructor, if it needs to be called.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      If that is true, the son class is destroyed later than father class? The sequence of destruction is diffrent from C++?
        The destructor is called when an object is destroyed, not the class.
        لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        In C++, if class Son inherits from class Father, then class Son inherits class Father’s methods and data. So it makes sense that when an object of class Son goes out of scope, the Son destructor is called to clean up the data which Son did not inherit, and then the Father destructor is called to clean up the data Son inherited from Father.

        But Perl* is different:

        Perl only provides method inheritance as a built-in feature. Attribute inheritance is left up [to] the class to implement.
        perlobj

        So, from the point of view of the data, there needn’t be any of the Father class in the Son class. So there may be nothing of the Father class to destroy, and no purpose in calling Father’s destructor.

        *Meaning the core Perl language, not the various OO frameworks mentioned by tobyink, below.

        Hope that helps,

        Update (23 Jan 2014): Added [to] to clarify the quote, and reduced the font size of the footnote.

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Objects (class instances) are represented by blessed references.

        When blessed reference goes out of scope (or otherwise becomes eligible for destruction), the cleanup code (only) calls a DESTROY method within the class that that reference is blessed into.

        Since your instance is of class B; only B's destructor is called automatically. It is up to the writer of class B to call any base-class or delegate destructors that need to be called from B's DESTROY method.

        As for the 'apparent order' or destructor calls, it all depends upon how you choose to trace them. If you output your trace messages on entrance to the destructors:

        package A; ... sub DESTROY { warn 'A::DESTROY' ... return; } package B; ... sub DESTROY { warn 'B::DESTROY'; my $self = shift; $self->SUPER::DESTROY; return; }

        Then class Bs destructor appears to be called before class A's. But do it this way:

        package A; ... sub DESTROY { ... warn 'A::DESTROY' return; } package B; ... sub DESTROY { my $self = shift; $self->SUPER::DESTROY; warn 'B::DESTROY'; return; }

        And it will appear to happen the other way around. So, appearances aren't everything.

        The main difference between Perl and C++ in this regard is that in Perl, the destructors are called recursively, and the programmer gets to decide which order things happen in (or if at all).

        In C++; destructors are called iteratively in a fixed (youngest to oldest) order.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        No, it happens in whatever order you want it to. The order is fixed in C++, completely but up to you in Perl. Like you found out, you can even completely skip calling a destructor.
Re: Why is the base class's destructor not called?
by tobyink (Abbot) on Jan 21, 2014 at 10:14 UTC

    In addition to BrowserUK's succinct and correct answer, I'll point out that most modern OO frameworks (including Moose, Moo, and Class::Tiny) allow you to specify a sub called DEMOLISH instead of DESTROY.

    In DEMOLISH there is no need to call SUPER::DEMOLISH - the OO framework automatically takes care of calling all parent DEMOLISH methods in the correct order.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1071432]
Approved by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2014-11-27 00:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (178 votes), past polls