Das ist eigentlich eine interessante Frage, denn es gibt zwei verschiedene Perl-Konzepte im Spiel.
Die erste ist - <FH>
bewirkt, dass eine Zeile aus der Datei gelesen wird.
Also, wenn Sie:
while (<FH>) {
Was du bist eigentlich bekommen ist:
while (defined $_ = <FH>) {
}
Und eine Zeile aus dem Datei-Handle gelesen wird, setzen in $_
und es wird dann getestet wenn es "definiert" ist (zB war das Lesen in Ordnung) - und wenn nicht, verlässt es die Schleife.
Da im ersten Beispiel $_
nicht gedruckt wird, wird diese Zeile effektiv verworfen.
Aber die Sekunde denken im Spiel ist über Kontext.
<FH>
funktioniert anders, wenn Sie tun:
my $line = <FH>;
Und:
my @lines = <FH>;
Im ersten Fall - eine einzige Zeile (bis zum nächsten $/
- standardmäßig \n
) gelesen wird. Im letzteren Fall wird die gesamte Datei gelesen, eine "Zeile" pro Array-Element.
Nun ist dies wichtig, weil die while
Schleife lesen - ist in einem skalaren Kontext (Zeile für Zeile). Aber der print <FH>
ist ein Listenkontext - und bewirkt, dass die ganze Datei gelesen (und gedruckt) wird.
Also in Ihrem ersten Beispiel - Sie wiederholen die Schleife einmal. Die erste Zeile verwerfen und alles andere drucken.
Und in der zweiten Schleife - Iteration einmal pro Zeile und Drucken jeder Zeile.
Der Unterschied ist auf einer 2-zeilige Datei nicht offensichtlich, aber:
#!/usr/bin/env perl
use strict;
use warnings;
my $count;
while (<DATA>) {
print "Loop count ", ++$count,"\n";
print '$_ is "', $_,"\"\n";
print "Printing <DATA>\n";
print <DATA>;
}
__DATA__
line 1
line 2
line 3
line 4
line 5
erhalten Sie folgende Ausgabe:
Loop count 1
$_ is "line 1
"
Printing <DATA>
line 2
line 3
line 4
line 5
Aber Ihr zweites Beispiel zu nehmen:
#!/usr/bin/env perl
use strict;
use warnings;
my $count;
while (<DATA>) {
print "Loop count ", ++$count,"\n";
print '$_ is "', $_,"\"\n";
print 'printing $_',"\n";
print $_;
}
__DATA__
line 1
line 2
line 3
line 4
line 5
Was gibt:
Loop count 1
$_ is "line 1
"
printing $_
line 1
Loop count 2
$_ is "line 2
"
printing $_
line 2
Loop count 3
$_ is "line 3
"
printing $_
line 3
Loop count 4
$_ is "line 4
"
printing $_
line 4
Loop count 5
$_ is "line 5"
printing $_
line 5
NB - es gibt keine chomp
in den oben genannten, so $_
enthält Zeilenumbrüche.
Und während wir dabei sind - diese Form von open
ist keine gute Praxis. Ich würde stattdessen vorschlagen:
open (my $input, '<', "103m.txt") or die $!;