I am trying to learn Perl here and the tutorial suggests the following code snippet after reading some file:
my $team_number = 42;
my $filename = 'input.txt';
open(my $fh, '<', $filename) or die "cannot open '$filename' $!";
my $found;
while(<$fh>) {
chomp;
last if($_ eq "Team $team_number");
}
die "cannot find 'Team $team_number'" if(eof $fh);
I don't quite understand why we need chomp, though. chomp removes the new line. So in each loop we remove the new line at the end of the line, but why? The script does throw an error if you remove the chomp, but I don't understand why.
I understand what chomping does, but I didn't get why that was necessary to match since we're already looping through all the lines - why would you then need to remove the new line? It was only after reading Kallol's post that I realised that eq would fail if not chomped, because the actual string that is looped, then, is Team 42\n. So that's why my question is different from other chomp questions: I didn't know why my code wasn't working without chomp and someone pointed me in the right direction.
It is reasonable that you don't want the new line when you load text and are working with it. The new lines organize text into a file, in memory you have arrays or other data structures. You don't have to chomp
it, you generally want to.
Why the code doesn't do what you intended without the chomp
has been explained by Kallol and Sobrique: a new-line remains in $_
which thus doesn't match (the string without a new line) so the file is read to the end and eof
returns true. See
chomp (orperldoc -f chomp
). I don't see that the script "throws an error" though, as you say. It doesn't for me, with or without `chomp'; it just never matches.
And there is another error even with chomp
, as noted by 123: if the matching string is the last line in the file, by the time the match is found the file has been read so eof
returns true and you get a statement that the string was not found. That you could fix by using a flag, for example (which you have right there), in which case you wouldn't be deciding via eof
any more.
That would be a very good thing, because what you have now has a little twisted (and rather brittle!) logic -- which is precisely how this last-line-error came about, of course.