2016-12-15 2 views
9

die perlxs documentation Lesen, kam ich zu dem Abschnitt auf dem OUTPUT Stichwort:Warum SvSETMAGIC() für Ausgabevariablen in einem XSUB einbeziehen?

xsubpp eine automatische SvSETMAGIC() für alle Parameter im OUTPUT des XSUB, außer RETVAL emittiert. Dies ist das normalerweise gewünschte Verhalten, da es sich darum kümmert, die 'set'-Magie bei der Ausgabe von Parametern korrekt aufzurufen (benötigt für Hash- oder Array-Element-Parameter, die sein müssen, wenn sie nicht existieren).

Ich bin nicht sicher, ob ich verstehen, warum ist set Magie gewünscht (und warum ist es nicht für RETVAL gewünscht)? Und warum wird set Magie für Hash- und Array-Element-Parameter benötigt?

Antwort

6

Alle Perl-Datenstrukturen unterstützen Magie, nicht nur SV s (trotz des Namens) und speziell für Hashes und Arrays dies ist die Grundlage für Dinge wie die tie Mechanismus oder Dinge wie fieldhash, die an der ein Analogon von schwachen Referenzen implementiert Ebene der Hash-Einträge. Da die OUTPUT Direktive angibt, welche Argumente vermutlich durch den C-Body von XSUB geändert werden und eine Variable mit set magic übergeben werden kann, kann das Setzen des Werts gemäß typemap ohne Aufruf des set-Handlers zu Inkonsistenzen führen Verhalten.

use Scalar::Util qw(weaken); 

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

Als Beispiel für Magie, weaken dekrementiert den Referenzzähler $foo und fügt Magie zurück zu $ref zeigen, so dass sie es gelöscht, wenn $foo Müll gesammelt wird.

Zusätzlich fügt es auch Magie auf $ref, diese wieder abzureißen Referenzierung, sonst, wenn $foo zerstört wird, würde $ref obwohl es nicht mehr an $foo zeigt an dieser Stelle gelöscht werden.

Wenn Sie $ ref als Argument verwenden, wird es auf dem Stapel aliased (weshalb $_[0] is assignable):

modifies_arguments($ref); 

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

Wenn modifies_arguments ein reines Perl ist es leicht zu sehen, warum dies angemessen ist, aber die Die gleichen Annahmen über die Korrektheit müssen natürlich für XSUBs gelten, weshalb OUTPUT verwendet wird, um zu markieren, welche Argumente auf den Wert der C-Level-Argumentvariablen am Ende des Funktionskörpers gesetzt werden, und magisch ausgelöst haben.

Dies trifft nicht auf RETVAL zu, da dies nicht technisch eine Aufgabe ist, sondern ein neues SV auf den Stapel geschoben wird, und jede gesetzte Magie wird behandelt, nachdem die Funktion durch die Zuweisung op (falls vorhanden) zurückkehrt.

+0

Vielen Dank für die Klärung! Was ist mit dem zitierten Text in Klammern: * '" benötigt für Hash- oder Array-Element-Parameter, die erstellt werden müssen, wenn sie nicht existierten "' *? Worauf bezieht sich das? Bedeutet das, dass "set" Magie nicht auf Skalare oder etwas anderes angewendet wird? –

+0

'mein @array; modifies_arguments ($ array [42]) 'würde das Array-Element nur dann erstellen, wenn es tatsächlich geändert wird, vgl. Autovivifizierung. Wenn das Array magisch ist, würde dies eine magische Einstellung für das Array selbst beinhalten. Dies gilt jedoch immer noch für Skalare, wie im obigen $ ref-Beispiel. – nothingmuch

2

Es ist ziemlich einfach. Wann immer Sie einem Skalar zuweisen, müssen Sie danach SvSETMAGIC() aufrufen, falls Magie damit verbunden ist.

Zuordnung zu RETVAL nicht zuweisen, um eine Perl-Variable, also Aufruf SvSETMAGIC(RETVAL) (es sei denn, Sie haben tatsächlich RETVAL geändert) wäre falsch.Wenn der zurückgegebene Wert einem anderen Skalar im Aufrufer zugewiesen ist, ruft die Zuweisung SvGETMAGIC auf dem zurückgegebenen Wert vor der Zuweisung und SvSETMAGIC auf der zugewiesenen Variablen nach der Zuweisung auf.

Verwandte Themen