[Munich-pm] Moose Demolish

Harald Joerg harald.joerg at ts.fujitsu.com
Mo Jan 27 03:30:58 PST 2014


Hello Robin,

> Has any of you had experience with Moose DEMOLISH (the Moosey way of doing
> DESTROY)?

I've used it in one case (to flush out some data to disk), without any
surprises.  I simply replaced DESTROY with DEMOLISH while moosifying the
module.

There seems to be a contradiction in your observations:

> normally DEMOLISH does not seem to be called.

> If I add exit(), it kills the application every time an object goes
> out of context...

If the application is killed I'd assume that DEMOLISH *is* being called
whenever an object goes out of scope???

It is also very surprising that the script does not end without an
exit() in the destructor.  Maybe there's another trap handler in place,
too?

This rather looks as if *some part* of your DEMOLISH is not performing
as expected.

I guess that at least one of the two major DESTROY pitfalls is in place
in your code:

   1) The object does not go out of scope when you expect it to: If
      there's any reference to the object in another variable, then the
      object goes out of scope when the other variable goes out of
      scope, maybe not before script termination.

   2) The code in DESTROY makes false assumptions about the availability
      of environments (can easily happen as a consequence of 1)) and
      fails silently.

The following example works as I'd expect.  Regardless of whether I hit
CTRL-C or not, I get two calls to DEMOLISH: One when the first object
goes out of scope, and the other when the second object vanishes during
termination. And CTRL-C *does* terminate the script, without exit() in
DEMOLISH, using sigtrap just gives a more verbose exit message.
====================================================================== #
Foo.pm package Foo;

use Moose;
use sigtrap qw/die normal-signals/;

sub DEMOLISH {
    my $object = shift;
    print STDERR "DEMOLISH: $object\n";
}

1;
======================================================================
# foo.pl
use strict;
use warnings;
use Foo;

my $f = Foo->new;
print STDERR "Foo object $f created\n";

$f = undef; # should cause call to DEMOLISH

$f = Foo->new;
print STDERR "New Foo object $f created\n";
my $b = $f;
$f = undef; # no demolition, there's another reference

print STDERR "Going to sleep\n";
sleep 10;
print STDERR "Exiting now\n";
======================================================================
# Just let it run
haj at ubuntu:~/host/test$ perl foo.pl
Foo object Foo=HASH(0x94b8970) created
DEMOLISH: Foo=HASH(0x94b8970)
New Foo object Foo=HASH(0x9a9ca3c) created
Going to sleep
Exiting now
======================================================================
# Interrupting during the 10 seconds sleep
haj at ubuntu:~/host/test$ perl foo.pl
Foo object Foo=HASH(0x8ff1970) created
DEMOLISH: Foo=HASH(0x8ff1970)
New Foo object Foo=HASH(0x95d5a3c) created
Going to sleep
^CCaught a SIGINT at foo.pl line 9
DEMOLISH: Foo=HASH(0x95d5a3c)
======================================================================

-- 
Good luck!
haj


> I'm a bit stuck... I want to run a cleanup in an object when it goes out of
> scope, but I'm a bit confusticated... normally DEMOLISH does not seem to be
> called.
> If I add this to the method
>
> use sigtrap qw/die normal-signals/;
>
> the DEMOLISH method is called, but if I kill the script with a CTRL-C, the
> DEMOLISH method also gets called (correct behaviour), but the script does not
> end, because the method does not contain an exit().
> If I add exit(), it kills the application every time an object goes out of
> context...
> I'm standing on the pipe here. (auf'm Schlauch stehen)... can someone give me a
> kickstart?
>
> Thanks!
>  
> Best winds,
> -Robin-
> ~:)


Mehr Informationen über die Mailingliste Munich-pm