Perl: Please explain to me the following behaviours of while()

一个人想着一个人 提交于 2019-12-10 18:11:11

问题


1.Why does while (<$filehandle>) iterate through a file seemlessly, but it doesn't iterate through lists or arrays without manipulating the array itself (like using while ($_ = shift @array){print $_}? How does this happen?

2.How is it that while ($var = @array){print $var} manages to iterate through the whole array? Shouldn't $var just get the number of indices in @array and return that value (so creating an infinite loop)?

From my understanding while() reads the conditionality of a statement and loops as long as it finds it true. What I find confusing though is its behaviour around filehandles, lists and the such.

Please help me understand more about while() as I find this operator very confusing sometimes.


回答1:


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.




回答2:


If you are going to use Perl, you will have to get comfortable with special cases.

In the first case, what's special is the diamond operator (<>).

Be careful with 2 as it will break on false values, IIRC.



来源:https://stackoverflow.com/questions/21950535/perl-please-explain-to-me-the-following-behaviours-of-while

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!