[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