Friday, July 06, 2007

Vorsicht! $_ und while

Schon allein wegen der Lesbarkeit sollte man nicht immer Spezialvariablen verwenden, aber manchmal sind sie einfach zu praktisch. Eine dieser praktischen Variablen ist $_. Die Variable kann unter anderem als Laufvariable in einer Schleife dienen, so zum Beispiel in einer for-Schleife:

for( @array ){
print $_;
}

Hier könnte man das $_ sogar weglassen weil print automatisch $_ nimmt, wenn nichts anderes angegeben ist.

Auch beim Einlesen von Dateien mit einer while-Schleife kann man $_ verwenden:

open my $fh, '<', $file or die $!; while( <$fh> ){
print;
}
close $fh;

Doch hier ist Vorsicht angesagt: Im Gegensatz zu for und foreach wird in der while-Schleife das $_ nicht lokalisiert. Das kann zu unangenehmen Nebeneffekten führen:

my $_ = 'test';
open my $fh, '<', $file or die $!; while( <$fh> ){
# mach irgendwas
}
close $fh;
print $_;

Hier kommt nicht wie gewünscht 'test' heraus, sondern "nichts" (genauer: ein undef). Während

my $_ = 'test';
for( @array ){
# mach irgendwas
}
print $_;

funktioniert.

Entweder muss man $_ selbst lokalisieren:

while( local $_ = <$fh> ){
}

oder man verwendet eine andere lexikalische Variable:

while( my $line = <$fh> ){
}

No comments: