ProgrammierungFull Stack Perl Developer

Welche Methoden zur Übergabe von Argumenten an Unterprogramme in Perl existieren und wie organisiert man die Übergabe per Referenz? Welche Besonderheiten gibt es bei der Arbeit mit @_ und wann ist die Übergabe per Referenz notwendig?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

In Perl erfolgt die Argumentation von Funktionen über das Array @_. Bei einem Aufruf des Unterprogramms befinden sich alle übergebenen Parameter in diesem Array, und ursprünglich handelt es sich um eine Liste und nicht um eine Kopie, das heißt, wenn Sie $_[0] ändern, ändern Sie das Original.

Übergabe durch Wert:

sub foo { my ($arg1, $arg2) = @_; $arg1 = 10; # Nur die lokale Variable ändert sich }

Übergabe per Referenz:

sub bar { my ($array_ref) = @_; push @$array_ref, 42; } my @data = (1,2,3); bar(\@data); # @data ist jetzt (1,2,3,42)

Besonderheiten:

  • Wenn Sie das ursprüngliche Array oder Hash ändern möchten, übergeben Sie eine Referenz.
  • Ordnungsgemäße Variablen ($foo, $bar) innerhalb von @_ sind Alias für die ursprünglichen Argumente, aber bei der Entpackung mit my ($a, $b) = @_ werden Kopien erstellt.
  • Bei der normalen Übergabe von Arrays und Hashes wird deren Inhalt in eine Liste entpackt, und Sie verlieren die Grenzen: Sie sollten eine Referenz übergeben oder die Spezifika von Verschiebungen nutzen.

Fangfrage

Wenn Sie in Perl eine Funktion ein Array so übergeben: myfunc(@arr) und innerhalb der Funktion auf $_[0] zugreifen, was wird dort sein?

Richtige Antwort: Dort wird das erste Element des Wertes des Arrays sein, nicht die Referenz auf das gesamte Array! Um ein Array als Ganzes zu übergeben, verwenden Sie die Referenz: myfunc(\@arr).

Beispiel:

sub print_first { print $_[0], " "; } my @a = qw/foo bar baz/; print_first(@a); # Gibt 'foo' aus, nicht die Referenz auf das Array print_first(\@a); # Gibt ARRAY(0x...) aus — Referenz auf das gesamte Array

Geschichte

In einem der Projekte wurde für die Modifikation eines globalen Hashes die Funktion so aufgerufen: update_hash(%global). Innen wurde $_[0] verändert. Infolgedessen wurde nur ein lokaler Ausschnitt des Argumentarrays geändert, und der globale Hash wurde nicht modifiziert. Die korrekte Lösung war die Übergabe einer Referenz: update_hash(\%global).

Geschichte

Bei der Entwicklung eines API-Frameworks wurden den Funktionen viele benannte Argumente übergeben, unter Verwendung eines Hashes. Manchmal wurde ein Array an die Funktion übergeben (aber nicht als Referenz!), und die Argumente "mischten sich", was zu Verwirrung führte: myfunc(@arr, %opts). Es stellte sich heraus, dass einige Schlüssel des Hashes durch die Werte des Arrays überschrieben wurden, und es war nicht einfach, den Fehler zu finden.

Geschichte

Bei der Implementierung der rekursiven Traversierung eines Baumes wollte man interne Elemente ändern. Die Arrays wurden "so wie sie sind" an die Funktion übergeben, nicht per Referenz. Sie erzeugten Kopien, und die Änderungen hatten keinen Einfluss auf den externen Kontext. Das Problem wurde durch den Wechsel zu dem Referenzstil behoben.