in reply to return weak reference

You have
-X->+---------+ -Y->| Node | -Z->+---------+ | ^ A B v | +---------+ | Node | +---------+

Your initial solution was to weaken "X", "Y" and "Z". That doesn't work because the creation of "Y" and "Z" is done outside of your control. You could weaken "B" instead. If for some reason, you can't do that (e.g. if you don't actually control the creation of those nodes), you could use a wrapper.

-X->+---------+ +---------+ -Y->| Wrapper |-J->| Node | -Z->+---------+ +---------+ | ^ A B v | +---------+ | Node | +---------+
The wrapper would has a destructor that deletes "A" or "B", breaking the loop, freeing the nodes. This wrapper has already been written for you: Object::Destroyer.
use Object::Destroyer qw( ); $tree = Object::Destroyer->new($tree);

Replies are listed 'Best First'.
Re^2: return weak reference
by flipper (Beadle) on Sep 02, 2010 at 09:52 UTC

    Thanks - I discussed the problem with a colleague, he suggested using a wrapper class, I thought some autoload magic could make it transparent - as ever, someone on CPAN already has a solution :-)

    As I understand it, Object::Destroyer will by default call the DESTROY method on the object it guards - this may close resources, but won't cause other references to the object to become undefined, which is what I was trying to achieve. Other packages had a file scoped reference to the object in question, which would become stale, if my understanding is correct.

    #!/usr/bin/perl -w use strict; our $other; my $main = foo->new(); print "undef object: ";<STDIN>; undef $main; print "exit: ";<STDIN>; package foo; use Object::Destroyer; sub new { my $package = shift; my $self = {}; bless $self => $package; $::other = $self; my $ret = Object::Destroyer->new($self); return $ret; } sub DESTROY { my $self =shift; print "DESTROYing $self\n"; #undef $self # doesn't help }

    outputs:

    undef object: DESTROYing foo=HASH(0x817f9d0) exit: DESTROYing foo=HASH(0x817f9d0)

    I had a look at the packages with file scoped references, and realised that I was just creating problems for myself - if I made objects call the constructor in question from a lexical/function scope, pretty much all of my problems go away - lexical scoping takes care of everything.

      As I understand it, Object::Destroyer will by default call the DESTROY method on the object it guards - this may close resources, but won't cause other references to the object to become undefined, which is what I was trying to achieve.

      There won't be anyone using the resource when O::D destroys it, because the O::D will only free it when there noone is using it anymore (i.e. when there are no more references to the O::D object).

      You're saying you want to the object to disappear before everyone's done with it (i.e. while they are still reference to it). Why would you want to do that?