This module could be implemented by simply looking at the reference count of the object in question, but there is no pure Perl method to my knowledge to accomplish this.
I have to admit if it were me I would forget the pure-perl restriction and just use weaken from Scalar::Util :-)
use Test::More tests => 1; use Scalar::Util qw(weaken); { my $original = bless {},'My::Test::Class'; weaken $original; ok !defined($original), '$object garbage collected'; }
which also has the advantage of working on non-blessed references.
The module name is still in flux, but as it is for testing the destruction of objects, I found Test::DESTROY appealing - any better idea?
Maybe Test::GarbageCollected, Test::Destroyed or Test::LastReference?
Test::DESTROY implies (to me) that you are testing the DESTROY method, not the fact that the object has been garbage collected.
The best method I came up to implement the inverse of destroyed_ok was to fork() the test a second time and use not destroyed_ok() there, observing the output, because most likely, the main program still holds a reference to the object if it assumes to be able to use the object afterwards. A simple look at the reference count would help of course ...
Again, I would just use weaken.
use Test::More tests => 1; use Scalar::Util qw(weaken); { my $original = bless {},'My::Test::Class'; my $copy = $original; weaken $original; ok defined($original), '$object still accessible'; }
Update: It will also fail for some pathological cases. Consider:
{ package Foo; sub new { my ($class, $name) = @_; bless {}, $class; }; my $In_global_destruction; END { $In_global_destruction++ }; my $Saved; sub DESTROY { my $self = shift; if ($In_global_destruction) { warn "really destroying $self\n"; } else { warn "not really destroying $self\n"; $Saved = $self; }; }; }; use strict; use warnings; use Test::More 'no_plan'; use Scalar::Util qw(weaken); my $copy; { my $original = Foo->new; $copy = $original; weaken $copy; destroyed_ok($original, '$original'); }; ok !defined($copy), '$original really destroyed'; __END__ # produces not really destroying Foo=HASH(0x512f0) ok 1 - $original was destroyed not ok 2 - $original really destroyed # Failed test (foo.pl at line 113) 1..2 # Looks like you failed 1 tests of 2. really destroying Foo=HASH(0x512f0)
which is, I guess, exactly the sort of subtle bug you're trying to detect :-)
In reply to Re: RFC: Test::Destroy ('Chasing shadows')
by adrianh
in thread RFC: Test::Destroy ('Chasing shadows')
by Corion
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |