ralphoweber has asked for the wisdom of the Perl Monks concerning the following question:

I am very worried about the purpose-specific e-mail reader I am writing. Its objective is to download e-mail messages with large PDF/ZIP file attachments, crack out the attachments into files, and pass the work to a pile of website builder code. Some of these PDF/ZIP attachments can be pushing 4 MB.

The e-mail reader program would best be designed to loop through the inbox until all e-mail message have been processed. This means that as soon as one 8 MB MIME e-mail message is finished, the program might start working on another one. Since the Email::MIME library is OO, it sure would be nice to DESTROY the objects from message 1 before beginning message 2.

The notion is ...

if( blah blah blah ) { my $email_text = join( '', $POPobject->get ); $MIMEobject = Email::MIME->new( $email_text ); };

If the coding style looks like FORTRAN, you caught me!

After all the MIME action is done for message 1 (when it's time for the wash-rinse-repeat cycle), I would like to send the multi-megabyte MIMEobject back to the free-space pool with:

$MIMEobject->DESTROY;

... but ... Although perltoot - Tom's object-oriented tutorial for perl describes DESTROY, it strongly hints that civilized programmers newer use it.

Can I be a barbarian in this case? Should I?

Fretting in Texas

Replies are listed 'Best First'.
Re: Can I use the OO DESTROY method ... for a good cause
by tobyink (Canon) on Jul 22, 2014 at 21:58 UTC

    The previous answers are good, but to sum them up:

    The DESTROY method is not something you call to destroy an object — it's something Perl calls when the object is being destroyed.

Re: Can I use the OO DESTROY method ... for a good cause
by AppleFritter (Vicar) on Jul 22, 2014 at 21:46 UTC

    Keep in mind that I'm fairly new to Perl myself, but...

    ...from what I know, the best course of action is to simply let the garbage collector do its work. Declare $MIMEobject as a lexical variable inside your if() { ... } block; once it goes out of scope and once there are no references to it anymore, the garbage collector will automatically reclaim it. There's no need to explicitely call DESTROY.

    If you want to release it ASAP, you could also undef it.

    May the more enlightened monks correct me if I'm wrong!

      This is correct; you should never explicitly invoke DESTROY, it will be called once the reverence reference count goes to zero. If you need to explicitly invoke DESTROY, you're doing it wrong.

      Update: Facepalm. Well spotted, Your Mother.


      #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

        Reverence count? The monastery has gone to your head. :P

Re: Can I use the OO DESTROY method ... for a good cause
by McA (Priest) on Jul 22, 2014 at 21:57 UTC

    Hi,

    in addition to what was said before. This snippet should show you that you don't need to explicitly call DESTROY:

    #!/usr/bin/perl use strict; use warnings; use 5.010; use Email::Stuffer; { package MyMail; use parent 'Email::MIME'; sub DESTROY { my ($self) = @_; say "in DESTROY"; } } # Get a Email::MIME object easily my $email = Email::Stuffer->from('huhu@yahoo.de') ->to('you@yahoo.de') ->text_body('Hi you!') ->email; foreach my $nr (1..2) { my $e = MyMail->new($email->as_string); say "Should be before DESTROY"; } say "Atfter Loop";

    As soon as your last reference to the object goes out of scope the DESTROY method gets called.

    Regards
    McA

Re: Can I use the OO DESTROY method ... for a good cause
by Anonymous Monk on Jul 22, 2014 at 22:02 UTC

    undef is what you want

    FWIW, DESTROY is for breaking circular references (parent/child), freeing xs/c-pointers and things like that ...

    Email::MIME doesn't have a DESTROY ...

Re: Can I use the OO DESTROY method ... for a good cause
by Anonymous Monk on Jul 22, 2014 at 21:50 UTC
    $MIMEobject->DESTROY;

    The DESTROY method will get called automatically when the last reference to the object goes away, you shouldn't call it yourself and it won't do what you want. What you want instead is undef $MIMEobject; (or $MIMEobject=undef;, same thing), and you'll want to undef any other references to the object that you might have.

    In general, you normally don't need to worry much about Perl's memory management, as long as you don't have circular references objects will be freed automatically when the last reference to them goes away. All that you have to make sure of is that you stop referring to the object.

Re: Can I use the OO DESTROY method ... for a good cause
by choroba (Cardinal) on Jul 23, 2014 at 11:44 UTC
    crack out the attachments into files
    This might be dangerous.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      To close this topic ...

      I have taken the "Don't worry, be happy" advise above. Actually, I have realized that I was already taking it in the following code fragment.

      foreach my $part ($MIMEhandle->subparts) { if( $part->content_type =~ m/text\/plain/i ) {return $part->body;}; };