2010-12-16 9 views

Odpowiedz

10

Myślę, że to problem z hermetyzacją. Jeśli biblioteka osób trzecich używa słabych informacji wewnętrznych, nie należy oczekiwać, że mój kod będzie wiedział z wyprzedzeniem, że gdy wykonam kopię odwołania, może nagle zniknąć. W Perlu zwykle oczekuje się, że ref będzie ważny tak długo, jak długo istnieje. Kiedy zadzwonisz pod numer weaken, zasadniczo obiecałeś, że podejmiesz niezbędne kroki, aby sprawdzić, czy referencja jest nadal ważna, zanim go użyjesz.

Jako drugi powód, dla którego interfejs osłabiający silną kopię słabego ref jest dość cieśninowy.

Kod, aby zrobić to samo, aby uzyskać silny ref, jeśli słaby ref stworzył słaby ref jest nieco bardziej skomplikowany.

my $new_ref; 
if (ref($old_ref) eq 'ARRAY') { 
    $new_ref = \@{$old_ref}; 
} 
elsif (ref($old_ref) eq 'HASH') { 
    $new_ref = \%{$old_ref}; 
} 
elsif (..... 

Jeśli wiesz, sędzia może być tylko jeden typ można zapisać if/elsif kaskadę i po prostu zrobić deref-reref, ale to jeszcze trudniej ocenić, dlaczego dereferencjonowane prostu wziąć nową adnotacje. Następny opiekun spróbuje "naprawić" twój kod.

3

Nie jestem pewien, dlaczego jest to domyślne zachowanie, ale tutaj jest rozwiązanie oparte na kodzie z dokumentacji Scalar::Util:

$ref = \$foo; 
$weak = isweak($ref);    # false 
weaken($ref); 
$weak = isweak($ref);    # true 

# copying a weak reference creates a new strong one 
$copy = $ref; 
$weak = isweak($copy);    # false 

# the solution is simply to weaken the copy 
$weaken($copy); 
$weak = isweak($copy);    # true 

Jeśli chciał zrobić podprogramu, które miały słabe odniesienie jako argument i zwrócono osłabioną kopię tego odniesienia, co byłoby łatwe przy użyciu kodu pokazanego powyżej.

+0

.. czy na pewno podprogram może zwrócić słabe odniesienie?Wydaje mi się, że każde osłabione odniesienie utworzone w podprogramie byłoby ZNISZCZONE, kiedy to odniesienie wykracza poza zakres podprogramu – Dancrumb

+0

Nie zwróci słabego wyniku odniesienia w ukrytej kopii (co spowoduje silne odniesienie są zwracane)? – Cameron

+2

@ Dancrumb, @Cameron, możesz zwrócić przeciążony obiekt, który przechowuje osłabione odniesienie. – ysth

12

Za każdym razem, gdy kopiujesz odniesienie do nowej zmiennej, licznik odwołań jest zwiększany. Dotyczy to kopiowania słabych lub silnych odniesień.

my $obj = {}; # 1 reference to {} stored in $obj 

my $copy = $obj; # 2 references 

weaken $obj;  # 1 reference 

w tym momencie, jeśli $copy wykracza poza zakres, liczba referencyjna spadnie do zera, a pamięć zostanie zwolniona. Załóżmy teraz następujący kod:

my $newref = $obj; # 2 references 

undef $copy;  # 1 reference 

Jeśli Perl zachowane słabego odniesienia w $newref, wówczas hash będzie nieoczekiwanie dealocated gdy $copy zdaje. Spowodowałoby to złamanie oczekiwań, że podczas kopiowania odniesienia, przynajmniej pozostanie tak długo, jak kopia.

Krótko mówiąc, jeśli słabe referencje utrzymywałyby się w obrębie zadania, zmusiłoby to do zaśmiecania kodu niezliczoną liczbą słabych punktów i wymagałoby innego sposobu odinstaluj zmienną, aby uniknąć nieuniknionych zmiennych problemów samobójczych.

Powiązane problemy