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

I'm having my first run-in with XS code requiring a nontrivial DESTROY method for my objects. I think the code is right, but I'd like to prove it with a test framework in the module's t/ directory.

What techniques do you use to write tests of DESTROY? Do you bring in help from the Devel namespace? Instrument DESTROY itself?

After Compline,
Zaxo

Replies are listed 'Best First'.
Re: Testing DESTROY Methods?
by robartes (Priest) on Oct 08, 2002 at 06:45 UTC
    I'd write a test script that uses your object and then lets it go out of scope, as in:
    package Camel; use strict; # Warning, do not use this constructor at home kids. # It's ugly and will scare the neighbours. sub new { bless {}; } sub DESTROY { print "My camel has sadly passed away.\n"; }
    And your test script would then do:
    use strict; use Camel; { my $jimmy=Camel->new(); } #$jimmy is now out of scope and will be DESTROYed.

    CU
    Robartes-

(tye)Re: Testing DESTROY Methods?
by tye (Sage) on Oct 08, 2002 at 15:01 UTC

    I find that it is best, when you free() a pointer, to also set the pointer to NULL. So have your DESTROY method croak if the pointer is already NULL. Then your test script can call DESTROY by hand and then let the object go out of scope and trap the error:

    my $fail= eval { { my $obj= My::Mod->new(); $obj->DESTROY(); } 1 }; print "not " unless $fail && $@ =~ /destroyed NULL/; print "ok 19\n";

    I hope that eval traps XS-based croak().

    And, of course, this won't work in Perl 6 if it doesn't implement reference counting.

            - tye (instruction at 0xBADC0DE5 tried to read 0x00000000)
Re: Testing DESTROY Methods?
by chromatic (Archbishop) on Oct 08, 2002 at 16:28 UTC

    DESTROY() is just another method. You can mock it to make sure it's called when you think it should be called, and you can call it with a mock object to make sure it does what you think it should do. The only real trick is knowing that it's called during an end of lifetime cleanup.