[Warszawa-pm] Scope::Guard
Piotr Roszatycki
piotr.roszatycki w gmail.com
Czw, 11 Paź 2012, 12:39:40 PDT
Tak, takich mechanizmów jest multum. Chodziło mi o to, że w Perlu nie
ma czegoś takiego jak destruktor obiektów. Przykładowy kod:
#!/usr/bin/perl
package My::Class;
use Moose;
has 'ref' => (is => 'rw', clearer => 'clear_ref');
sub free {
my ($self) = @_;
$self->clear_ref;
}
sub DESTROY {
warn "memory leak of @_" if ${^GLOBAL_PHASE} eq 'DESTRUCT';
}
package main;
my $obj1 = My::Class->new();
my $obj2 = My::Class->new();
# zapętlam
$obj1->ref($obj2);
$obj2->ref($obj1);
#$obj1->free;
#$obj2->free;
# zero efektu jeśli powyższe jest zakomentowane
undef $obj1;
undef $obj2;
i teraz trick polega na tym, że ten DESTROY to nie jest destruktor! To
jest jedynie procedura, która uruchamia się już po tym, jak obiekt
ulega destrukcji. W tym powyższym przypadku wykona się dopiero na
koniec programu (global destruction), stąd komunikat o "memory leak".
Jeśli zrobię metodę, która ręcznie zwolni mi zapętlone referencje i
wywołam ją explicite albo pośrednio z użyciem tego Scope::Guard, to
faktycznie pamięć się zwolni. Jednak to trzeba ręcznie obsłużyć z
zewnątrz klasy. Jak jakaś ciapa programista zapomni wywołać "free" to
kaplica, bo sam undef obiektu to za mało. Fajnie byłoby, gdyby
zwalniając $obj1 ten "free" wywołałby się automatycznie, albo
odwrotnie: wywołując "free" zwolniłby się automatycznie $obj1.
Pzdr.
2012/10/11 Zbigniew Łukasiak <zzbbyy w gmail.com>
>
> http://search.cpan.org/~chocolate/Scope-Guard-0.20/lib/Scope/Guard.pm
>
> tak a propos rozmowy na ostatnim spotkaniu
Więcej informacji o liście Warszawa-pm