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

I can't recall the name of the module that lets me associate a destructor with a specific thing. I've got an Archive::Extract object which has been extracted out to a temporary directory. I'd like to remove the directory as soon as the last reference to it is gone. The code to do this is simple enough and the need common enough that I'm sure it's already on CPAN but that I just can't recall the name. Help?

$tmpdir = File::Temp::tmpdir(); $archive = Archive::Extract->new( archive => ... ); $archive->extract( to => $tmpdir ); # Hooks DESTROY for this object. $archive = on_cleanup( $archive, sub { # rm -rf $tmpdir } );

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Replies are listed 'Best First'.
Re: Per-object DESTROY
by Corion (Patriarch) on Jul 07, 2007 at 17:18 UTC

    tilly's ReleaseAction has that, so you could collect "things to do on destruction" in your object with it:

    use ReleaseAction 'on_release'; sub foo { ... my $actions = $self->actions; push @$actions, on_release { `rm -rf "$tmpdir"` }; };

    And as soon as $self goes out of scope, hopefully all release actions will also fire. By attaching them to the object, you get the bonus option of optionally cancelling them should you have a reason to. Of course, you need to be careful that your closures don't close over your object, but you know that.

Re: Per-object DESTROY
by Joost (Canon) on Jul 07, 2007 at 22:29 UTC

      It's not my object. I'd need to either install a DESTROY method into the Archive::Extract object violating its implementation or write an object which I could hang my DESTROY-time code off of. tilly's ReleaseAction handles this case nicely. I just pass in my destroy code and make sure the ReleaseAction object is destroyed at the same time as the object.

      ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

        ReleaseAction would require you to synchronize the out-of-scope moment between the two objects.

        Wouldn't the classy way be to subclass Archive::Extract just inheriting its methods, and to implement your own DESTROY method in the subclass that invokes SUPER::DESTROY as its last action?

Re: Per-object DESTROY
by sgt (Deacon) on Jul 08, 2007 at 14:06 UTC

    I guess you mean Scope::Guard related patterns. adamk's Object::Destroyer could be useful too although it targets cyclic referencing

    cheers --stephan update: look at the modules present in the SEE ALSO section of Scope::Guard for various interesting approaches to a similar problem
Re: Per-object DESTROY
by Anonymous Monk on Jul 08, 2007 at 05:43 UTC
Re: Per-object DESTROY
by dmitri (Priest) on Jul 12, 2007 at 03:53 UTC
    I think you can achieve this using subclassing, something like the following (not tested):
    package MyArchive; use base 'Archive::Extract'; sub set_on_destroy { my ($self, $sub) = @_; $self->{'_on_destroy'} = $sub; } sub DESTROY { my $self = shift; if ('CODE' eq ref(my $code = $self->{'_on_destroy'})) { $code->($self); } } 1;