Perl ist eine Sprache mit ausgeprägter Kontextabhängigkeit: Das Ergebnis eines Ausdrucks hängt davon ab, wie sein Ergebnis verwendet wird. Historisch gesehen hat dies die Sprache extrem flexibel gemacht, jedoch können selbst erfahrene Entwickler Fehler machen, wenn sie die Besonderheiten von skalarischem und listenbasiertem Kontext nicht berücksichtigen.
Die Frage tauchte in den ersten Versionen von Perl auf, als angenommen wurde, dass dasselbe Operation entweder ein Array oder einen einzelnen Wert zurückgeben kann – zum Beispiel kann der Aufruf der Funktion localtime entweder eine Liste oder einen String zurückgeben, je nach Situation.
Problem ist, dass eine falsche Behandlung des Kontexts zu unerwarteten Fehlern führt: z.B. überflüssige Elemente, leere Ergebnisse oder seltsames Verhalten von logischen Ausdrücken.
Lösung – immer klar verstehen, in welchem Kontext eine Funktion oder ein Ausdruck aufgerufen wird, die eingebaute Funktion wantarray in eigenen Unterprogrammen verwenden und implizite Vermischung von Kontexten vermeiden.
Beispielcode:
sub may_return { return wantarray ? (1, 2, 3) : "scalar result"; } my @arr = may_return(); # gibt (1,2,3) zurück my $val = may_return(); # gibt "scalar result" zurück
Schlüsselfunktionen:
Kann man im Inneren einer Funktion bestimmen, ob ein Ausdruck im void-Kontext verwendet wird?
Antwort: Nein, nur skalarisch oder listenbasiert. In Perl 5 gibt es keine Funktion, die den void-Kontext innerhalb eines Unterprogramms bestimmt – die Funktion wantarray gibt in diesem Fall undef zurück, jedoch für ein anderes Verhalten.
Beispielcode:
sub example { return wantarray ? (1,2) : wantarray ? undef : "scalar"; # inkorrekt }
Kann eine Funktion je nach Kontext unterschiedliche Datentypen zurückgeben?
Antwort: Ja, das ist vollkommen zulässig und wird häufig verwendet.
Hängt das Verhalten von Operatoren (z.B. shift, pop) vom Kontext ab?
Antwort: Ja. Zum Beispiel, wenn shift innerhalb einer Funktion aufgerufen wird – es hängt davon ab, ob @_ (global oder lexikalisch) verwendet wird, und ob das Ergebnis als skalar oder als Liste übergeben wird.
Ein Entwickler hat eine Funktion geschrieben, die immer eine Liste zurückgibt, ohne den skalarischen Kontext zu berücksichtigen. Wenn man diese Funktion im skalarischen Kontext aufruft, erhält man nur das letzte Element der Liste.
Vorteile:
Nachteile:
In der Funktion wird wantarray verwendet, und es wird entweder eine Liste oder ein sinnvoller Skalar oder undef zurückgegeben.
Vorteile:
Nachteile: