Ihre Frage zu print
in foreach
wird beantwortet, hier ist ein wenig mehr auf $_
.
Von General Variables in perlvar
Hier sind die Orte, an denen Perl übernehmen wird $_
auch wenn Sie es nicht verwenden:
Die folgenden Funktionen verwenden $_
als Standardargument:
- abs, alarm, chomp, hacken, chr, chroot, cos, definiert, eval, evalbytes, exp, fc, glob, hex, int, lc, lcfirst, Länge, log, lstat, mkdir, oct, ord, pos, drucken, printf, quotemeta, readlink, readpipe, ref, erfordern, reverse (nur im skalaren Kontext), rmdir, sagen, sin, split (für seine zweites Argument), sqrt, stat, study, uc, ucfirst, unlink, entpacken.
Alle Dateitests (-f
, -d
) mit Ausnahme -t
, die standardmäßig STDIN. Siehe -X
Die Pattern-Matching-Operationen m//
, s///
und tr///
(aka y///
), wenn ohne =~
Operator verwendet.
Die Standard-Iteratorvariable in einer foreach
-Schleife, wenn keine andere Variable angegeben wird.
Die implizite Iteratorvariable in den Funktionen grep()
und map()
.
Die implizite Variable given()
.
Der Standard Ort, um den nächsten Wert oder Eingabesatz zu setzen, wenn ein <FH>
, readline
, readdir
oder each
Betrieb Ergebnis um sich als einziges Kriterium eines while
Test getestet wird. Außerhalb eines while
Tests wird dies nicht passieren.
$_
ist standardmäßig eine globale Variable.
Wie Sie sehen können, ist es fast überall verfügbar, und es ist in der Tat eine Menge verwendet. Beachten Sie, dass die Seite perlvar viel mehr ähnliche Variablen beschreibt, von denen viele gut zu wissen sind.
Hier ist ein Beispiel. Berücksichtigen Sie, dass wir Zeilen aus einer Datei lesen, diejenigen, die nur Leerzeichen enthalten oder mit (Kommentare) beginnen, löschen möchten und andere sie durch Leerzeichen in Wörter aufteilen möchten.
open my $fh, '<', $file or die "Can't open $file: $!";
while (<$fh>)
{
next if not /\S/;
next if /^\s*#/;
my @words = split;
# do something with @words ...
}
Mal sehen, wie viele Verwendungen von $_
in dem obigen Beispiel sind. Hier ist ein äquivalentes Programm
while (my $line = <$fh>)
{
next if not $line =~ m/\S/; # if not matching any non-space character
next if $line =~ m/^\s*#/; # if matching # after only (possible) spaces
my @words = split ' ', $line; # split $line by ' ' (any white space)
# do something with @words ...
}
Vergleichen Sie diese beiden
die Dateikennung <$fh>
im while
Zustand gelesen zuordnet $_
, dann in der Schleife.
regulärer Ausdruck Match-Operator arbeitet standardmäßig auf $_
. Die m
selbst kann fallen gelassen werden.
split
standardmäßig splits $_
. Wir verwenden auch den anderen Standard, für den das Muster die Zeichenfolge aufteilen soll, nämlich ' '
(jede beliebige Menge Leerraum).
sobald wir $line = <$fh>
das Geschäft mit $_
tun ausgeschaltet ist (es wird in der Schleife nicht definiert), und wir haben $line
überall zu nutzen. Also entweder tun Sie dies oder tun while (<$fh>)
und $_
verwenden.
Um dies zu verdeutlichen alle ein bisschen weiter, lassen Sie uns die längste aktivierte Wort auf jeder
use List::Util 'max';
my $longest_cap = max map { length } grep { /^[A-Z]/ } @words;
Die grep die Liste in @words
nimmt
Linie finden und wendet den Block zu jedem Element. Jeder Artikel ist
$_
zugeordnet und steht somit dem Code innerhalb des Blocks als
$_
zur Verfügung. Dies ist, was die Regex standardmäßig verwendet. Diejenigen, die die Bedingung erfüllen, werden an
map übergeben, was auch iteriert, sie
$_
zuzuordnen, was natürlich der Standard für
length ist. Schließlich wählt
max
von
List::Util die größte.
Beachten Sie, dass $_
nie tatsächlich geschrieben wird und keine temporäre Variable benötigt wird.
Hier ist ein Teil der relevanten Dokumentation. Die I/O Operators in perlop diskutiert while (<$fh>)
und alle möglichen verwandten Dinge. Der Regex-Teil befindet sich in Regexp Quote-Like Operators in perlop und in perlretut. Schauen Sie sich auch split an.
Defaults werden von anderen regelmäßig und lesen Code geschrieben verwenden Sie müssen sie verstehen. Wenn Sie schreiben Sie Ihren eigenen Code, obwohl Sie wählen können, ob $_
oder nicht zu verwenden, da man immer eine lexikalische Variable anstelle davon einführen kann.
Also, wann zu verwenden $_
als Standard (die nicht geschrieben werden muss) und wann nicht?
Die korrekte Verwendung der Standardwerte, insbesondere $_
, kann zu klareren und besser lesbaren Codes führen. Was im Allgemeinen besser Code bedeutet. Aber es ist durchaus möglich, dies zu weit zu treiben und mit einem obskuren, kniffligen und spröden Code zu enden. Also guter Geschmack ist gefragt.
Ein weiterer Fall ist, wenn einige Teile des Codes von $_
für ihre Standardwerte profitieren, während an anderen Stellen müssen Sie dann explizit $_
verwenden. Ich würde sagen, wenn $_
mehr als einmal oder zweimal in einem Codeabschnitt gesehen wird, bedeutet das, dass es stattdessen eine richtig benannte Variable geben sollte.
Insgesamt im Zweifel einfach alles benennen.
Siehe [perldoc -f print] (http://perldoc.perl.org/functions/print.html): * Wenn LIST weggelassen wird, wird $ _ an das aktuell ausgewählte Ausgabehandle ausgegeben. * '$ _' ist das Standardargument für print, das heißt, wenn Sie 'print' ohne Argument aufrufen, wird' $ _' gedruckt. – Dada
Siehe über '$ _' in [Allgemeine Variablen in perlvar] (http://perldoc.perl.org/perlvar.html#General-Variables). Es gibt _many_ Dinge in Perl, die es als Standard verwenden, und es ist eines der am häufigsten verwendeten Geräte. – zdim
Wird jemand eine Antwort schreiben? Es ist eine gültige Frage, obwohl das Lesen der Dokumente ausreichen sollte. Nur dieses spezielle Dokument zu finden, ist schwer. Wir haben grundsätzlich die Antwort mit den obigen Kommentaren, aber Kommentare sind nicht für Antworten. Ich werde warten, falls einer von euch beschließt, die Antwort zu schreiben. – simbabque