2016-12-15 22 views
9

Czytając perlxs documentation, doszedłem do sekcji na kluczowych OUTPUT:Dlaczego włączyć SvSETMAGIC() na zmiennych wyjściowych w XSUB?

xsubpp emituje automatycznego SvSETMAGIC() dla wszystkich parametrów w sekcji wyjściu XSUB wyjątkiem retval. Jest to zwykle pożądane zachowanie, ponieważ dba o prawidłowe wywoływanie "ustawionej" magii dla parametrów wyjściowych (potrzebnych dla parametrów mieszania lub elementów tablicy, które muszą być utworzone , jeśli nie istniały).

Nie jestem pewien, czy rozumiem, dlaczego potrzebny jest set magia (i dlaczego nie jest pożądane dla RETVAL)? I dlaczego potrzebna jest magia set dla parametrów mieszania i elementów tablicy?

Odpowiedz

6

Wszystkie struktury danych Perla obsługują magii, nie tylko SV s (mimo nazwy) i specjalnie dla skrótów i tablic jest to podstawa dla rzeczy jak mechanizm tie lub rzeczy jak fieldhash który implementuje analog słabych referencji Pod poziom wpisów hash.

Ponieważ dyrektywa wskazuje, które argumenty byłyby prawdopodobnie zmodyfikowane przez treść C w XSUB, a zmienna zawierająca ustawioną magię może zostać przekazana, ustawienie wartości zgodnie z mapą typu bez wywoływania procedury ustawiania tabelki może spowodować niespójność. zachowanie.

use Scalar::Util qw(weaken); 

my $foo; 
my $ref = \$foo; 
weaken($ref); 

Jako przykład magii weaken zmniejsza liczbę referencyjną $foo i dodaje magii skierowany z powrotem do $ref tak, że jest wyczyszczone, kiedy $foo dostaje śmieci zebrane.

Dodatkowo dodaje również ustawić magii $ref, aby zburzyć ten tył odsyłania, inaczej kiedy $foo jest zniszczony, $ref będzie wyczyszczone, chociaż w tym momencie to już nie wskazując na $foo.

Jeśli używasz $ ref jako argument pobiera aliasem na stosie (dlatego $_[0] is assignable):

modifies_arguments($ref); 

sub modifies_arguments { 
    $_[0] = "blah"; # set magic is invoked to tear down the back referencing 
} 

Jeśli modifies_arguments jest czystym Perl to łatwo zrozumieć, dlaczego jest to stosowne, ale te same założenia co do poprawności muszą oczywiście obowiązywać dla XSUB-ów, dlatego też do oznaczania, które argumenty będą miały wartość ustawioną na dowolną zmienną argumentu poziomu C na końcu treści funkcji, i ustawiono wyzwalanie magiczne, stosuje się OUTPUT.

Nie ma to zastosowania do RETVAL, ponieważ nie jest to technicznie zadanie, ale raczej przesuwanie nowego SV na stos, a jakakolwiek ustawiona magia będzie obsługiwana po zwróceniu funkcji przez przydział op (jeśli jest).

+0

Dzięki za wyjaśnienie tego! A co z cytowanym tekstem w nawiasach: * '" potrzebne do parametrów mieszania lub tablicy elementów, które muszą zostać utworzone, jeśli nie istnieją "' *? Do czego odnosi się "to? Czy to oznacza, że ​​magia "set" nie jest stosowana do skalarów czy czegoś innego? –

+0

'my @array; modifies_arguments ($ array [42]) "utworzyłoby element tablicy tylko wtedy, gdy zostało faktycznie zmodyfikowane, cf. autoweryfikacja. Jeśli tablica jest magiczna, wymagałoby to ustawienia magii samej tablicy. Jednak w dalszym ciągu dotyczy to skalarów, tak jak w powyższym przykładzie '$ ref'. – nothingmuch

2

To całkiem proste. Za każdym razem, gdy przypisujesz wartość skalarowi, musisz później zadzwonić na nią pod numer SvSETMAGIC(), na wypadek gdyby była powiązana z nią magia.

Przypisanie do RETVAL nie przypisuje zmiennej Perl, więc wywołanie SvSETMAGIC(RETVAL) (chyba że zmodyfikowałeś) byłoby błędne.Jeśli zwrócona wartość jest przypisana do innego skalaru w wywołującym, to zadanie wywoła SvGETMAGIC zwróconej wartości przed przypisaniem i SvSETMAGIC dla przypisanej zmiennej po przypisaniu.