Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weak References in Perl

How to create weak references to the objects in perl, so when object goes out of scope, the reference count is released?
I have tried using the DESTROY sub to break the circular references.

sub DESTROY{  
my $p = shift;  
delete $p->{__tree__};  
delete $p->{tokenizers};  
delete $p->{toke};  
}

Please help.

like image 352
Shail Avatar asked Mar 29 '26 15:03

Shail


2 Answers

You can't "call" destroy - the problem here is that perl works on reference counting - each reference to a thing is counted, and it is only when the ref count drops to zero, that it may be released/destroyed/garbage collected.

DESTROY is a special method that is called within an object to do cleanup tasks when this happens. It doesn't delete the object, it just lets it do some final tidying when it dies.

Have a look at the Scalar::Util module. It includes the weaken method which does exactly what you asked.

The lvalue $ref will be turned into a weak reference. This means that it will not hold a reference count on the object it references. Also when the reference count on that object reaches zero, the reference will be set to undef. This function mutates the lvalue passed as its argument and returns no value.

This is useful for keeping copies of references, but you don't want to prevent the object being DESTROY-ed at its usual time.

like image 87
Sobrique Avatar answered Mar 31 '26 04:03

Sobrique


From perldoc:

You can break circular references by creating a "weak reference". A weak reference does not increment the reference count for a variable, which means that the object can go out of scope and be destroyed. You can weaken a reference with the weaken function exported by the Scalar::Util module.

Here's how we can make the first example safer:

use Scalar::Util 'weaken';
my $foo = {};
my $bar = { foo => $foo };
$foo->{bar} = $bar;
weaken $foo->{bar};

The reference from $foo to $bar has been weakened. When the $bar variable goes out of scope, it will be garbage-collected. The next time you look at the value of the $foo->{bar} key, it will be undef.

This action at a distance can be confusing, so you should be careful with your use of weaken. You should weaken the reference in the variable that will go out of scope first. That way, the longer-lived variable will contain the expected reference until it goes out of scope.

like image 35
serenesat Avatar answered Mar 31 '26 06:03

serenesat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!