Приведу пример:
| Код | #!/usr/bin/perl
use strict; use warnings;
use Scalar::Util;
use Devel::Leak::Object qw(GLOBAL_bless);
my $group = UsersGroup->new(); $group->add_user(User->new());
print $group->get_users()->[0]->get_group()->get_name(), $/; undef $group;
package UsersGroup;
sub new { my $class = shift; return bless { name => 'Test', users => [] }, $class; }
sub add_user { my ($self, $user) = @_; push(@{$self->{users}}, $user); # Scalar::Util::weaken($self->{users}->[-1]); # делаем ссылку слабой $user->set_group($self); return 1; }
sub get_name { return shift->{name}; }
sub get_users { return shift->{users}; }
package User;
sub new { my $class = shift; return bless { group => undef }, $class; }
sub set_group { my ($self, $group) = @_; $self->{group} = $group; # Scalar::Util::weaken($self->{group}); # делаем ссылку слабой return 1; }
sub get_group { return shift->{group}; }
|
В примере я использую модуль Devel::Leak::Object, который показывает объекты, остающиеся после автоматической "сборки мусора" интерпретатором. Без использования слабой ссылки мы получаем
| Код | Test Tracked objects by class: User 1 UsersGroup 1
|
т.е. в памяти осталось два объекта: один класса UsersGroup, второй - User.
После раскомментирования строки создания слабой ссылки в классе User получаем:
| Код | Test Tracked objects by class:
|
т.е. никаких объектов в памяти не остается.
Если же мы сделаем слабой ссылку на объект User в классе UsersGroup, то получим
| Код | Can't call method "get_group" on an undefined value at weaken_test.pl line 13. Tracked objects by class:
|
т.к. никаких ссылок, кроме слабой на объект User нет, он уничтожается сразу после создания слабой ссылки, о чем свидетельствует сообщение об ошибке. |