Interesting question.
I wonder if you could do something with weaken from Scalar::Util for this. You could have the object itself keep a strong reference to itself, and then all other references would have to be weak. Then the object could drop itself at will.
The problem is that a copy of a weak reference is not weak, so you can't just weaken yourself in the constructor and pass that out. The rest of the code would have to be disciplined enough to weaken every new object and every copy of an object's reference.
Update: I've been fooling around with this a little bit thinking that I could use overload, but it hasn't worked. The problem is that you can't really overload '=' so that the object returns a weakened reference to itself. The best I've come up with is to have a somewhat different constructor.
package Weakling;
use Scalar::Util qw( weaken );
sub new {
die 'Call as Weakling->new(my $new_weakling)'
if ( defined wantarray or scalar @_ < 2 );
my $self = {};
$self->{self} = $self;
bless $self, 'Weakling';
$_[1] = $self;
weaken $_[1];
return;
}
sub suicide { delete $_[0]->{self} }
package main;
use Scalar::Util qw( isweak );
use Test::More 'no_plan';
Weakling->new(my $weakling);
isa_ok( $weakling, 'Weakling' );
ok( isweak $weakling, 'got a weak object' );
$weakling->suicide();
ok( ! defined $weakling, 'weakling killed itself' );
Weakling->new($weakling);
isa_ok( $weakling, 'Weakling' );
ok( isweak $weakling, 'got a weak object' );
TODO: { local $TODO = "Can't overload '='";
my $w2 = $weakling;
ok( isweak $w2, 'copy of weakling is weak' );
}
...but of course this won't work for you if you already have lots of construction in the traditional my $n = Obj->new() style. |