Dies ist der Befehl perlreftut, der beim kostenlosen Hosting-Anbieter OnWorks mit einer unserer zahlreichen kostenlosen Online-Workstations wie Ubuntu Online, Fedora Online, dem Windows-Online-Emulator oder dem MAC OS-Online-Emulator ausgeführt werden kann
PROGRAMM:
NAME/FUNKTION
perlrefftut – Marks sehr kurzes Tutorial über Referenzen
BESCHREIBUNG
Eine der wichtigsten neuen Funktionen in Perl 5 war die Möglichkeit, komplizierte Prozesse zu verwalten
Datenstrukturen wie mehrdimensionale Arrays und verschachtelte Hashes. Um diese zu aktivieren, ist Perl 5
Es wurde eine Funktion namens „Referenzen“ eingeführt, und die Verwendung von Referenzen ist der Schlüssel zur Verwaltung
komplizierte, strukturierte Daten in Perl. Leider gibt es eine Menge komischer Syntax
lernen, und die Haupthandbuchseite kann schwer zu verstehen sein. Das Handbuch ist ziemlich vollständig und
Manchmal empfinden die Leute das als Problem, weil es schwierig sein kann zu sagen, was wichtig ist und was
was nicht.
Glücklicherweise müssen Sie nur 10 % des Inhalts der Hauptseite kennen, um 90 % davon zu erhalten
Nutzen. Diese Seite zeigt Ihnen diese 10 %.
Mit wem Sie Needs Kompliziert Daten-Management Strukturen?
Ein ständig auftretendes Problem besteht darin, einen Hash zu benötigen, dessen Werte Listen sind. Perl hat
Hashes natürlich, aber die Werte müssen Skalare sein; Es können keine Listen sein.
Warum möchten Sie einen Hash von Listen? Nehmen wir ein einfaches Beispiel: Sie haben eine Stadtdatei
und Ländernamen, etwa so:
Chicago, USA
Francfort, Allemagne
Berlin, Deutschland
Washington, USA
Helsinki, Finnland
New York, USA
und Sie möchten eine Ausgabe wie diese erstellen, bei der jedes Land einmal erwähnt wird und dann ein
alphabetische Liste der Städte in diesem Land:
Finnland: Helsinki.
Deutschland: Berlin, Frankfurt.
USA: Chicago, New York, Washington.
Der natürliche Weg, dies zu tun, besteht darin, einen Hash zu haben, dessen Schlüssel Ländernamen sind. Damit verbundenen
Zu jedem Ländernamenschlüssel gehört eine Liste der Städte in diesem Land. Jedes Mal, wenn Sie a lesen
Geben Sie die Eingabezeile ein, teilen Sie sie in ein Land und eine Stadt auf und schlagen Sie bereits die Liste der Städte nach
bekanntermaßen in diesem Land liegt, und fügen Sie die neue Stadt der Liste hinzu. Wenn du fertig bist
Lesen Sie die Eingabe, iterieren Sie wie gewohnt über den Hash und sortieren Sie jede Liste der Städte vor Ihnen
Drucke es aus.
Wenn Hashwerte keine Listen sein könnten, haben Sie verloren. Sie müssten wahrscheinlich alle Städte kombinieren
irgendwie in eine einzelne Zeichenfolge umwandeln, und wenn es dann an der Zeit wäre, die Ausgabe zu schreiben, müssten Sie es tun
Teilen Sie die Zeichenfolge in eine Liste auf, sortieren Sie die Liste und wandeln Sie sie wieder in eine Zeichenfolge um. Das ist
chaotisch und fehleranfällig. Und es ist frustrierend, weil Perl bereits vollkommen gut ist
Listen, die das Problem lösen würden, wenn Sie sie nur verwenden könnten.
Die Die Lösung
Als Perl 5 auf den Markt kam, waren wir bereits bei diesem Design festgefahren: Hash-Werte müssen
Skalare sein. Die Lösung hierfür sind Referenzen.
Eine Referenz ist ein Skalarwert, der bezieht sich zu ein ganzes Array oder einen ganzen Hash (oder nur
über alles andere). Namen sind eine Art Referenz, mit der Sie bereits vertraut sind.
Denken Sie an den Präsidenten der Vereinigten Staaten: ein unordentlicher, unbequemer Beutel voller Blut und Knochen.
Aber um über ihn zu sprechen oder ihn in einem Computerprogramm darzustellen, brauchen Sie nur das
einfache und praktische Skalarzeichenfolge „Barack Obama“.
Referenzen in Perl sind wie Namen für Arrays und Hashes. Sie sind Perls privates, internes Element
Namen, sodass Sie sicher sein können, dass sie eindeutig sind. Im Gegensatz zu „Barack Obama“ nur eine Referenz
bezieht sich auf eine Sache, und Sie wissen immer, worauf es sich bezieht. Wenn Sie einen Verweis auf eine haben
Array können Sie das gesamte Array daraus wiederherstellen. Wenn Sie einen Verweis auf einen Hash haben, dann
kann den gesamten Hash wiederherstellen. Aber die Referenz ist immer noch ein einfacher, kompakter Skalarwert.
Sie können keinen Hash haben, dessen Werte Arrays sind. Hashwerte können nur Skalare sein. War
bin dabei geblieben. Aber eine einzelne Referenz kann auf ein ganzes Array verweisen, und Referenzen sind es auch
Skalare, so dass Sie einen Hash von Referenzen auf Arrays haben können, der sich ähnlich wie ein Hash verhält
von Arrays, und es wird genauso nützlich sein wie ein Hash von Arrays.
Wir werden später auf dieses Stadt-Land-Problem zurückkommen, nachdem wir etwas über die Syntax gesehen haben
Verwaltung von Referenzen.
Syntax
Es gibt nur zwei Möglichkeiten, eine Referenz zu erstellen, und nur zwei Möglichkeiten, sie zu verwenden, sobald Sie sie haben.
Making Referenzen
Marke Regel 1
Wenn Sie vor einer Variablen ein „\“ setzen, erhalten Sie eine Referenz auf diese Variable.
$aref = \@array; # $aref enthält jetzt eine Referenz auf @array
$href = \%hash; # $href enthält jetzt eine Referenz auf %hash
$sref = \$scalar; # $sref enthält jetzt eine Referenz auf $scalar
Sobald die Referenz in einer Variablen wie $aref oder $href gespeichert ist, können Sie sie kopieren oder speichern
Es ist genau das Gleiche wie jeder andere Skalarwert:
$xy = $aref; # $xy enthält jetzt eine Referenz auf @array
$p[3] = $href; # $p[3] enthält jetzt eine Referenz auf %hash
$z = $p[3]; # $z enthält jetzt eine Referenz auf %hash
Diese Beispiele zeigen, wie Sie mit Namen auf Variablen verweisen. Manchmal möchte man es
Erstellen Sie ein Array oder einen Hash, der keinen Namen hat. Dies ist analog zu der Art und Weise, wie Sie es möchten
um die Zeichenfolge „\n“ oder die Zahl 80 verwenden zu können, ohne sie in einem benannten Speicher speichern zu müssen
Variable zuerst.
Marke Regel 2
„[ ITEMS ]“ erstellt ein neues, anonymes Array und gibt einen Verweis auf dieses Array zurück. "{ ARTIKEL
}“ erstellt einen neuen, anonymen Hash und gibt einen Verweis auf diesen Hash zurück.
$aref = [ 1, "foo", undef, 13 ];
# $aref enthält jetzt eine Referenz auf ein Array
$href = { APR => 4, AUG => 8 };
# $href enthält jetzt eine Referenz auf einen Hash
Die Referenzen, die Sie von Regel 2 erhalten, sind die gleichen Referenzen, die Sie von Regel erhalten
1:
# Das:
$aref = [ 1, 2, 3 ];
# Macht das Gleiche wie folgt:
@array = (1, 2, 3);
$aref = \@array;
Die erste Zeile ist eine Abkürzung für die folgenden beiden Zeilen, außer dass dies nicht der Fall ist
Erstellen Sie die überflüssige Array-Variable @array.
Wenn Sie nur „[]“ schreiben, erhalten Sie ein neues, leeres anonymes Array. Wenn Sie nur „{}“ schreiben, werden Sie
Holen Sie sich einen neuen, leeren anonymen Hash.
Die richtigen Referenzen
Was können Sie mit einer Referenz machen, wenn Sie sie einmal haben? Es ist ein Skalarwert, und wir haben gesehen
dass Sie es wie jeden Skalar als Skalar speichern und wieder zurückerhalten können. Es gibt
Nur zwei weitere Möglichkeiten, es zu verwenden:
Verwenden Sie die Regel 1
Sie können anstelle des Namens eines Arrays jederzeit einen Array-Verweis in geschweiften Klammern verwenden.
Zum Beispiel „@{$aref}“ anstelle von @array.
Hier sind einige Beispiele dafür:
Anordnungen:
@a @{$aref} Ein Array
reverse @a reverse @{$aref} Das Array umkehren
$a[3] ${$aref}[3] Ein Element des Arrays
$a[3] = 17; ${$aref}[3] = 17 Zuweisen eines Elements
In jeder Zeile stehen zwei Ausdrücke, die dasselbe bewirken. Die linkshändigen Versionen funktionieren
auf dem Array @a. Die rechten Versionen arbeiten mit dem Array, auf das verwiesen wird
$aref. Sobald sie das Array gefunden haben, auf dem sie arbeiten, führen beide Versionen dasselbe aus
die Arrays.
Die Verwendung einer Hash-Referenz ist genau das gleiche:
%h %{$href} Ein Hash
Schlüssel %h Schlüssel %{$href} Holen Sie sich die Schlüssel aus dem Hash
$h{'red'} ${$href}{'red'} Ein Element des Hashs
$h{'red'} = 17 ${$href}{'red'} = 17 Zuweisen eines Elements
Was auch immer Sie mit einer Referenz machen möchten, Verwenden Sie die Regel 1 sagt dir, wie es geht. Sie gerade
Schreiben Sie den Perl-Code, den Sie geschrieben hätten, um dasselbe mit einem regulären Benutzer zu tun
Array oder Hash, und ersetzen Sie dann den Array- oder Hash-Namen durch „{$reference}“. "Wie mache ich
„Eine Schleife über ein Array ausführen, wenn ich nur eine Referenz habe?“ Nun, um eine Schleife über ein Array durchzuführen, Sie
würde schreiben
für mein $element (@array) {
...
}
Ersetzen Sie also den Array-Namen @array durch die Referenz:
für mein $element (@{$aref}) {
...
}
„Wie drucke ich den Inhalt eines Hash aus, wenn ich nur eine Referenz habe?“ Schreiben Sie zuerst
der Code zum Ausdrucken eines Hashs:
für meinen $key (keys %hash) {
print "$key => $hash{$key}\n";
}
Und ersetzen Sie dann den Hash-Namen durch die Referenz:
für meinen $key (keys %{$href}) {
print "$key => ${$href}{$key}\n";
}
Verwenden Sie die Regel 2
Verwenden Sie die Regel 1 ist alles, was Sie wirklich brauchen, denn es zeigt Ihnen, wie man absolut alles macht
Sie müssen jemals mit Referenzen zu tun haben. Aber das häufigste, was man mit einem Array oder einem macht
Hash besteht darin, ein einzelnes Element zu extrahieren, und das Verwenden Sie die Regel 1 Notation ist umständlich. Also da
ist eine Abkürzung.
„${$aref}[3]“ ist zu schwer zu lesen, daher können Sie stattdessen „$aref->[3]“ schreiben.
„${$href}{red}“ ist zu schwer zu lesen, daher können Sie stattdessen „$href->{red}“ schreiben.
Wenn $aref einen Verweis auf ein Array enthält, dann ist „$aref->[3]“ das vierte Element des
Array. Verwechseln Sie dies nicht mit $aref[3], dem vierten Element eines Totals
anderes Array, eines mit dem täuschenden Namen @aref. $aref und @aref haben nicht die gleiche Beziehung
dass $item und @item sind.
Ebenso ist „$href->{'red'}“ Teil des Hashs, auf den sich die Skalarvariable $href bezieht.
vielleicht sogar einer ohne Namen. $href{'red'} ist Teil des trügerisch benannten %href-Hashs.
Man vergisst leicht, das „->“ wegzulassen, und wenn man es tut, erhält man seltsame Ergebnisse
Ihr Programm ruft Array- und Hash-Elemente aus völlig unerwarteten Hashes und Arrays ab
waren nicht diejenigen, die Sie verwenden wollten.
An Beispiel
Sehen wir uns ein kurzes Beispiel dafür an, wie nützlich das alles ist.
Denken Sie zunächst daran, dass „[1, 2, 3]“ ein anonymes Array mit „(1, 2, 3)“ erstellt und
gibt Ihnen einen Verweis auf dieses Array.
Denken Sie jetzt darüber nach
@a = ( [1, 2, 3],
[4, 5, 6],
[7, 8, 9]
);
@a ist ein Array mit drei Elementen, und jedes Element ist eine Referenz auf ein anderes Array.
$a[1] ist eine dieser Referenzen. Es bezieht sich auf ein Array, das Array enthält „(4, 5,
6)“, und weil es sich um einen Verweis auf ein Array handelt, Verwenden Sie die Regel 2 sagt, dass wir schreiben können
$a[1]->[2], um das dritte Element aus diesem Array abzurufen. $a[1]->[2] ist die 6. Ebenso gilt:
$a[0]->[1] ist die 2. Was wir hier haben, ist wie ein zweidimensionales Array; Du kannst schreiben
$a[ROW]->[COLUMN], um das Element in einer beliebigen Zeile und Spalte des Arrays abzurufen oder festzulegen.
Die Notation sieht immer noch etwas umständlich aus, deshalb gibt es noch eine Abkürzung:
Pfeil Regel
Zwischen zwei tiefgestellte, der Pfeil ist optional.
Anstelle von $a[1]->[2] können wir $a[1][2] schreiben; es bedeutet dasselbe. Anstatt
„$a[0]->[1] = 23“, wir können schreiben „$a[0][1] = 23“; es bedeutet dasselbe.
Jetzt sieht es wirklich wie zweidimensionale Arrays aus!
Sie können sehen, warum die Pfeile wichtig sind. Ohne sie hätten wir schreiben müssen
„${$a[1]}[2]“ statt $a[1][2]. Für dreidimensionale Arrays lassen sie uns schreiben
$x[2][3][5] anstelle des unlesbaren „${${$x[2]}[3]}[5]“.
Die Lösung
Hier ist die Antwort auf das Problem, das ich zuvor gestellt habe, nämlich die Neuformatierung einer Stadt- und Stadtdatei
Ländernamen.
1 mein %table;
2 while (<>) {
3 Stück;
4 my ($city, $country) = split /, /;
5 $table{$country} = [] sofern nicht vorhanden $table{$country};
6 push @{$table{$country}}, $city;
7}
8 foreach $country (Sortierschlüssel %table) {
9 print „$country:“;
10 my @cities = @{$table{$country}};
11 print join ', ', sort @cities;
12 print ".\n";
13}
Das Programm besteht aus zwei Teilen: Die Zeilen 2–7 lesen die Eingabe und erstellen eine Datenstruktur und
Zeilen 8-13 analysieren die Daten und drucken den Bericht aus. Wir werden einen Hash haben, %table,
deren Schlüssel Ländernamen sind und deren Werte Verweise auf Arrays von Städtenamen sind.
Die Datenstruktur sieht folgendermaßen aus:
%Tisch
+-------+---+
| | | +-----------+--------+
|Deutschland| *---->| Frankfurt | Berlin |
| | | +-----------+--------+
+-------+---+
| | | +----------+
|Finnland| *---->| Helsinki |
| | | +----------+
+-------+---+
| | | +---------+------------+----------+
| USA | *---->| Chicago | Washington | New York |
| | | +---------+------------+----------+
+-------+---+
Wir schauen uns zunächst die Ausgabe an. Angenommen, wir haben diese Struktur bereits, wie drucken wir sie aus?
aus?
8 foreach $country (Sortierschlüssel %table) {
9 print „$country:“;
10 my @cities = @{$table{$country}};
11 print join ', ', sort @cities;
12 print ".\n";
13}
%table ist ein gewöhnlicher Hash, und wir erhalten daraus eine Liste von Schlüsseln, sortieren die Schlüssel und führen eine Schleife durch
wie gewohnt über die Tasten. Die einzige Verwendung von Referenzen findet sich in Zeile 10. $table{$country} sieht aus
Füge den Schlüssel $country im Hash hinzu und rufe den Wert ab, der eine Referenz auf ein Array von ist
Städte in diesem Land. Verwenden Sie die Regel 1 sagt, dass wir das Array wiederherstellen können, indem wir sagen
„@{$table{$country}}“. Zeile 10 ist genau so
@cities = @array;
außer dass der Name „array“ durch die Referenz „{$table{$country}}“ ersetzt wurde. Der
„@“ weist Perl an, das gesamte Array abzurufen. Nachdem wir die Liste der Städte erhalten haben, sortieren wir sie,
Machen Sie mit und drucken Sie es wie gewohnt aus.
Die Linien 2-7 sind in erster Linie für den Aufbau der Struktur verantwortlich. Hier sind sie
wieder:
2 while (<>) {
3 Stück;
4 my ($city, $country) = split /, /;
5 $table{$country} = [] sofern nicht vorhanden $table{$country};
6 push @{$table{$country}}, $city;
7}
Die Zeilen 2-4 erhalten einen Stadt- und Ländernamen. Zeile 5 prüft, ob das Land bereits vorhanden ist
als Schlüssel im Hash vorhanden. Ist dies nicht der Fall, verwendet das Programm die Notation „[]“ (Marke Regel
2), um ein neues, leeres, anonymes Array von Städten zu erstellen, und installiert einen Verweis darauf
in den Hash unter dem entsprechenden Schlüssel ein.
Zeile 6 installiert den Städtenamen im entsprechenden Array. $table{$country} enthält jetzt a
Bezug auf die Vielfalt der Städte, die es bisher in diesem Land gab. Zeile 6 ist genau so
push @array, $city;
außer dass der Name „array“ durch die Referenz „{$table{$country}}“ ersetzt wurde. Der
„push“ fügt am Ende des Arrays, auf das verwiesen wird, einen Städtenamen hinzu.
Es gibt einen schönen Punkt, den ich übersprungen habe. Zeile 5 ist unnötig und wir können sie loswerden.
2 while (<>) {
3 Stück;
4 my ($city, $country) = split /, /;
5 #### $table{$country} = [] sofern nicht vorhanden $table{$country};
6 push @{$table{$country}}, $city;
7}
Wenn in %table bereits ein Eintrag für das aktuelle $country vorhanden ist, ist nichts anders.
Zeile 6 findet den Wert in $table{$country}, das eine Referenz auf ein Array ist, und
Schieben Sie $city in das Array. Aber was macht es, wenn $country einen Schlüssel enthält, sagen wir „Griechenland“?
das ist noch nicht in %table?
Das ist Perl, also macht es genau das Richtige. Man sieht, dass man „Athen“ vorantreiben will
auf ein Array, das nicht existiert, sodass hilfreicherweise ein neues, leeres, anonymes Array für erstellt wird
Sie, installiert es in %table und schiebt dann „Athens“ darauf. Das nennt man
„Autovivifizierung“ – Dinge automatisch zum Leben erwecken. Perl sah, dass der Schlüssel nicht vorhanden war
im Hash, so dass automatisch ein neuer Hash-Eintrag erstellt wurde. Perl hat gesehen, dass Sie es verwenden wollten
den Hash-Wert als Array, also wurde ein neues leeres Array erstellt und ein Verweis darauf installiert
es automatisch in den Hash ein. Und wie üblich hat Perl das Array um ein Element länger gemacht
Halten Sie den neuen Stadtnamen.
Die Ruhe
Ich habe versprochen, Ihnen 90 % des Nutzens mit 10 % der Details zu geben, und das bedeutet, dass ich gegangen bin
90 % der Details heraus. Nachdem Sie nun einen Überblick über die wichtigen Teile haben, sollte dies der Fall sein
Es wird einfacher sein, die perlref-Handbuchseite zu lesen, in der 100 % der Details erläutert werden.
Einige der Highlights von perlref:
· Sie können auf alles verweisen, einschließlich Skalare, Funktionen und anderes
Verweise.
· Im Verwenden Sie die Regel 1, können Sie die geschweiften Klammern weglassen, wenn das Ding darin ein ist
atomare Skalarvariable wie $aref. Beispielsweise ist @$aref dasselbe wie „@{$aref}“ und
$$aref[1] ist dasselbe wie „${$aref}[1]“. Wenn Sie gerade erst anfangen, möchten Sie vielleicht
Machen Sie es sich zur Gewohnheit, immer die geschweiften Klammern einzufügen.
· Dadurch wird das zugrunde liegende Array nicht kopiert:
$aref2 = $aref1;
Sie erhalten zwei Verweise auf dasselbe Array. Wenn Sie „$aref1->[23]“ ändern und dann schauen
Bei „$aref2->[23]“ sehen Sie die Änderung.
Um das Array zu kopieren, verwenden Sie
$aref2 = [@{$aref1}];
Dabei wird die Notation „[...]“ verwendet, um ein neues anonymes Array zu erstellen, und $aref2 wird a zugewiesen
Verweis auf das neue Array. Das neue Array wird mit dem Inhalt des initialisiert
Array, auf das $aref1 verweist.
Ebenso können Sie zum Kopieren eines anonymen Hashs verwenden
$href2 = {%{$href1}};
· Um zu sehen, ob eine Variable eine Referenz enthält, verwenden Sie die Funktion „ref“. Es gibt true if zurück
sein Argument ist eine Referenz. Eigentlich ist es noch ein bisschen besser: Es kehrt zurück
„HASH“ für Hash-Referenzen und „ARRAY“ für Array-Referenzen.
· Wenn Sie versuchen, eine Referenz wie eine Zeichenfolge zu verwenden, erhalten Sie Zeichenfolgen wie
ARRAY(0x80f5dec) oder HASH(0x826afc0)
Wenn Sie jemals eine Zeichenfolge sehen, die so aussieht, wissen Sie, dass Sie eine Referenz ausgedruckt haben
aus Versehen.
Ein Nebeneffekt dieser Darstellung ist, dass Sie mit „eq“ sehen können, ob zwei Referenzen vorhanden sind
beziehen sich auf dasselbe. (Aber normalerweise sollten Sie stattdessen „==“ verwenden, da es viel ist
Schneller.)
· Sie können eine Zeichenfolge wie eine Referenz verwenden. Wenn Sie die Zeichenfolge „foo“ als verwenden
Array-Referenz, es wird als Referenz auf das Array @foo angesehen. Dies nennt man a
weich Referenz or symbolisch Referenz. Die Deklaration „use strict ‚refs‘“ deaktiviert
Diese Funktion kann zu allen möglichen Problemen führen, wenn Sie sie versehentlich verwenden.
Möglicherweise möchten Sie lieber zu perllol statt zu perlref übergehen. Es werden Listen von Listen und besprochen
mehrdimensionale Arrays im Detail. Danach sollten Sie mit perldsc fortfahren; es ist eine Daten
Strukturkochbuch, das Rezepte für die Verwendung und das Ausdrucken von Hash-Arrays und Hashes zeigt
von Arrays und anderen Arten von Daten.
Zusammenfassung
Jeder braucht zusammengesetzte Datenstrukturen, und in Perl erhält man sie auf folgende Weise
Verweise. Für die Verwaltung von Referenzen gibt es vier wichtige Regeln: Zwei für die Erstellung
Referenzen und zwei für deren Verwendung. Sobald Sie diese Regeln kennen, können Sie die meisten davon ausführen
Wichtige Dinge, die Sie mit Referenzen tun müssen.
Credits
Autor: Mark Jason Dominus, Plover Systems („[E-Mail geschützt] ")
Dieser Artikel erschien ursprünglich in Die Perl Journal ( http://www.tpj.com/ ) Band 3, Nr. 2.
Nachdruck mit freundlicher Genehmigung.
Der Originaltitel war Verstehen Referenzen Heute.
Vertrieb Bedingungen
Copyright 1998 The Perl Journal.
Diese Dokumentation ist kostenlos; Sie können es unter den gleichen Bedingungen weitergeben und/oder ändern
als Perl selbst.
Unabhängig von ihrer Verbreitung werden hiermit alle Codebeispiele in diesen Dateien in platziert
die öffentliche Domäne. Es ist Ihnen gestattet und ermutigt, diesen Code in Ihren eigenen Programmen zu verwenden
zum Spaß oder zum Profit, wie Sie es für richtig halten. Ein einfacher Kommentar im Code, der Kredit gibt, wäre
höflich, aber nicht erforderlich.
Nutzen Sie perlreftut online über die Dienste von onworks.net