Let's start by looking at while(<$filehandle>)
. This is actually Perl shorthand for this:
while (defined($_ = <$filehandle>)) {
print $_;
}
So each time through the loop, you're reading the next line from the file, and if it is not defined, you'll quit out of the loop. If it is defined, you'll continue. As you expect, while
will loop as long as the condition evaluates to true.
You'll be able to see that by running perl -MO=Deparse program.pl
. You can also check out the documentation under Loop Control. The diamond operator is the same thing as the subroutine readline (it reads the next line from the file).
In the case for while ($_ = shift @array){print $_}
, you will be modifying the array when the condition for the while
loop is checked. The subroutine shift removes the first element of the array and returns it. So $_
will be set correctly, but your array will start losing elements.
In the next case, while ($var = @array){print $var}
, $var
will be equal to the number of elements in the array. It's because you're using @array
in a scalar context. This will mostly likely evaluate to true because from perlsyn
The number 0, the strings '0' and "" , the empty list () , and undef
are all false in a boolean context. All other values are true.
Take this one-liner for example:
perl -le 'my @array = qw(a b c d e); my $var = @array; print $var'
It will print the number 5
, because there are 5 elements in the array. The while
loop will not execute if you have 0 elements in your array, and it will be stuck in an infinite loop if there are 1 or more elements in it.
Example:
### This code will print 5 forever ###
my @array = qw(hi this is a test);
my $var;
while ( $var = @array ) {
print "$var\n";
}
For your question 2, it sounds like you are getting different results but this does get stuck in a loop for me.