Reputation: 189
I am trying to read two lines at a time with a while
loop but am getting this error:
line 1
line 2
line 3
Use of uninitialized value in concatenation (.) or string at ....
Use of uninitialized value in concatenation (.) or string at ....
Use of uninitialized value in concatenation (.) or string at ....
Script:
#!/usr/bin/perl
use warnings;
use strict;
my $count = 1;
while ( my $two_lines = <DATA> . <DATA> ) {
print $two_lines;
}
__DATA__
line 1
line 2
line 3
Upvotes: 0
Views: 231
Reputation: 34120
What you may not be aware of is that
while ( my $line = <DATA> ){ ... }
is short for
while ( defined( my $line = <DATA> ) ){ ... }
That transformation only occurs for simple constructs like that.
If it didn't check for defined
ness then it could skip the last line if it contained nothing but 0
.
( the other lines are guaranteed to have a line separator as well, so they would continue to work correctly. )
A way to get it to work similarly for one or two lines at a time is:
# take advantage of the built-in transformation
while ( my $two_lines = <DATA> ) {
$two_lines .= <DATA> // '';
... # your code here
}
Upvotes: 0
Reputation: 360
It's not really an error, its just a warning. You should get 2 warnings on even line number files, and 3 warnings on odd numbered files. When it comes through the while expression the first time, it reads from the first time fine, then when it reads the second time, the filehandle is empty, and it prints the warning. Because it returned something the first time, it will execute the contents of the while loop. the last time, it will evaluate the filestream twice, get nothing and abort the loop, but warn both times it tries to concaticate the empty reads. If you need a while loop i would do
while ( my $first_lines = <DATA> ) {
if (my $second_line = <DATA> ){
print $first_lines . $second_line;
}else{
print $first_lines
break;
}
}
Upvotes: 2
Reputation: 385789
readline
aka <$fh>
returns undef to signal the end of the file (or an error). You're not checking for that. Fix:
while (1) {
defined( my $line1 = <DATA> )
or last;
defined( my $line2 = <DATA> )
or die("Premature end of file\n");
print($line1 . $line2);
}
Upvotes: 1
Reputation: 118605
The readline operator <HANDLE>
returns undef when reading from an exhausted filehandle (in scalar handle). So the first warning comes in the 2nd iteration of the while
loop when you read the (missing) 4th line from DATA
.
The next two warnings come from the 3rd iteration, when you call <DATA>
twice on an exhausted filehandle.
You can fix this by using an expression that will not be undef
. Since you're using perl >=v5.16, you can use
while (my $line = (<DATA> // '') . (<DATA> // '')) { ...
Upvotes: 3