[Moscow.pm] weaken with функции
Vladimir Timofeev
vovkasm на gmail.com
Вс Фев 27 23:39:29 PST 2011
2011/2/28 Ivan Petrov <i.petro.77.00 на gmail.com>:
>
>> > некий код:
>> >
>> > sub method
>> > {
>> > my $self = shift;
>> > ...
>> > $self->{handle} = AnyEvent::Handle fh => $fh, on_error => sub {
>> > $self->{error} = $! };
>> > ...
>> > }
>> >
>> > получается что каллбек цепляет ссылку на $self и из за него деструктор
>> > вызван не может быть до тех пор пока handle не уничтожится.
>> > в случае с просто ссылками - понятно: weaken на них. а здесь куда можно
>> > weaken натравить чтобы деструктор у такого объекта работал?
>>
>> После $self = shift; добавить weaken($self);
>
> В этом случае если эта работа делается внутри конструктора, то добавление
> такого weaken приводит к тому что вместо указателя на объект возвращается
> какая-то ахинея.
>
> вот такой тест:
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
>
> use utf8;
> use open qw(:std :utf8);
>
> package TestW;
> use AnyEvent::Handle;
> use Scalar::Util qw(weaken);
>
>
> sub new {
> my ($class, $fh) = @_;
>
> my $self = bless { } => $class;
> # weaken $self;
> $self->{handle} = new AnyEvent::Handle
> fh => $fh,
> on_error => sub { $self->{error} = $! };
> return $self;
> }
>
> package main;
> use Data::Dumper;
>
> my $o = new TestW(\*STDIN);
> print Dumper $o;
>
> печатает на выходе следующее:
>
> $VAR1 = bless( {
> 'handle' => bless( {
> '_activity' => '1298875336.78856',
> '_ractivity' => '1298875336.78856',
> '_wactivity' => '1298875336.78856',
> 'fh' => \*::STDIN,
> 'oobinline' => 1,
> 'on_error' => sub { "DUMMY" }
> }, 'AnyEvent::Handle' )
> }, 'TestW' );
>
> теперь если раскоментировать weaken, то объект превратится в простой хеш:
>
> $VAR1 = {
> 'handle' => bless( {
> '_activity' => '1298875430.28919',
> '_ractivity' => '1298875430.28919',
> '_wactivity' => '1298875430.28919',
> 'fh' => \*::STDIN,
> 'oobinline' => 1,
> 'on_error' => sub { "DUMMY" }
> }, 'AnyEvent::Handle' )
> };
>
> и как быть?
Я бы так делал:
sub new {
my ($class, $fh) = @_;
my $self = bless( {}, $class);
my $me = $self;
weaken $me;
$self->{handle} = AnyEvent::Handle->new(
fh => $fh,
on_error => sub {
return unless $me;
$me->{error} = $!
}
);
return $self;
}
Просто когда вы делаете weaken на ссылку на объект, на который ссылок
нет больше, то этот объект естественно уничтожается сразу.
> Perl 5.10.1
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>
>
--
Vladimir Timofeev <vovkasm на gmail.com>
Подробная информация о списке рассылки Moscow-pm