« Lazy bum | Main | Software Patents in Europe »

Weaken references in Perl

In case you need circular structures in Perl, you should known about Scalar::Util and it's weaken function.

See this example:

package T;

sub DESTROY {
  my $self = shift;
  print STDERR "Bye bye: $self->{name}\n";
}

package main;
use Scalar::Util qw( weaken );

{
  my $a = bless { name => 'a' }, 'T';
  my $b = bless { name => 'b' }, 'T';

  $a->{b} = $b;
  $b->{a} = $a;
}
print "Should see a destroy 'a' and 'b', but you wont...\n";

{
  my $c = bless { name => 'c' }, 'T';
  my $d = bless { name => 'd' }, 'T';

  $c->{d} = weaken($d);
  $d->{c} = weaken($c);
}
print "Should see a destroy 'c' and 'd'!\n";
print "Now you'll see a destroy 'a' and 'b'\n";

The output is this:

Should see a destroy 'a' and 'b', but you wont...
Bye bye: d
Bye bye: c
Should see a destroy 'c' and 'd'!
Now you'll see a destroy 'a' and 'b'
Bye bye: b
Bye bye: a

The problem is that in the first block, although the $a and $b are no longer in scope, each one holds a reference to the other, and that prevents them both from being destroyed.

In the second block, each one of $c and $d takes a weak reference to each other. Weak references don't increment the reference count internal to all Perl variables, so at the end of the block, they are correctly destroyed.

You've warned.

Contacts

melo@simplicidade.org (XMPP/email)
+351 302 029 050 (voice)
melopt (Skype)

IronMan challenge

Iron Man badge Are you ready to be an Iron Man? Join the challenge and find out! (what is the meaning of this little man?)

Moosaico

Junta-te!

Recent Comments

Powered by Disqus
Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.2