jrasillo has asked for the wisdom of the Perl Monks concerning the following question:

Does anyone know if while loops could be used like this
while (@array){};
The reason why I'm not using for or foreach is because I need to change the loop control variable...

Replies are listed 'Best First'.
Re: infinite loop on while (@array)
by Juerd (Abbot) on Mar 27, 2002 at 07:39 UTC

    Does anyone know if while loops could be used like this while (@array){};

    That's possible, and will repeat the block while @array is true. @array in scalar context returns the number of elements, so this will loop while @array has elements. If you don't remove elements from it, it wil loop indefinitely.

    With Perl, you can create any loop you want. There's a number of useful loop forms already: while, do while, do until, and two kinds of for(each). If that's not sufficient for whatever you want (you didn't really describe what you want), you can create any loop yourself. Bare blocks are considered loops, but they are executed only once if you don't change that yourself. You can use redo and last together with if and unless to construct your very own, very specific loop.

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

Re: infinite loop on while (@array)
by belg4mit (Prior) on Mar 27, 2002 at 07:24 UTC
    Only if you plan on destroying the array in the process, as in this loops as long as scalar @array > 1

    You might want to reconsider for and foreach, or better yet try to give a more thorough explanation of why you believe you cannot use them.

    --
    perl -pe "s/\b;([st])/'\1/mg"

Re: infinite loop on while (@array)
by dws (Chancellor) on Mar 27, 2002 at 07:24 UTC
    Does anyone know if while loops could be used like this

    Yes, but that code fragment won't do what you expect.

    There are lots of ways to do things in Perl. Please say more about what, exactly, you're trying to do.

Re: infinite loop on while (@array)
by cchampion (Curate) on Mar 27, 2002 at 07:40 UTC
    If you want to change a variable, then use it in addition to the array.
    my $count = 10; while ($count) { #do something to array print $array[$count--]; } # alternative $count =0; for (@array) { print "$count $_\n"; # $_ is the current array item $count = &something_complex; }
    Anyway, the loop you want to use is an infinite loop, unless you empty the array. It will test TRUE as long as the array has more than 0 elements.
    If you need a real infinite loop, then this one could suit you better:
    my $count =0; while(1) { # do something to the array $count = &something_strange last if (test_exit_condition); }

      If you need a real infinite loop, then this one could suit you better:

      Or the expressionless C-style loop. (The while(1) loop will be converted into it to optimize, so why not type it yourself?) They're a nice visual way to say: this is infinite, while while(1) and while(0) don't differ a lot.

      for (;;) { # ... }

      U28geW91IGNhbiBhbGwgcm90MTMgY
      W5kIHBhY2soKS4gQnV0IGRvIHlvdS
      ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
      geW91IHNlZSBpdD8gIC0tIEp1ZXJk
      

        <pedant class="minor">

          The while(1) loop will be converted into it to optimize

          Im fairly sure that if you look into the documentation again that the c style for loop is actually converted into a while() block. Not the other way round.

          Hmm, just doublechecked perlsyn and it seems that they arent clear, nor is the camel, as to whether these are actually handled internally as forms of each other. However the camel has the following interesting addition to the perlsyn:

          The for loop can be defined in terms of the corresponding while loop.

          Thus, the following:

          for ($i = 1; $i < 10; $i++) { ... }
          is the same as:

          $i = 1; while ($i < 10) { ... } continue { $i++; }
          (Defining the for loop in terms of a continue block allows us to preserve the correct semantics even when the loop is continued via a next statement. This is unlike C, in which there is no way to write the exact equivalent of a continued for loop without chicanery.)
          <super>emphasis added by me</super>
        </pedant>

        Yves / DeMerphq
        ---
        Writing a good benchmark isnt as easy as it might look.

Re: infinite loop on while (@array)
by shotgunefx (Parson) on Mar 27, 2002 at 07:45 UTC
    Assuming the loop variable is the current element of array you can use the following form of for(each) that will alias $_ to the actual variable and change it all you want. Just make sure it's a variable and not a list literal like for(1..10)
    #!/usr/bin/perl -w use strict; my @array = (1..15); print "Numbers are ",join(", ",@array),"\n"; foreach(@array){ next if $_ % 2; # Skip odd numbers. last if $_ > 10; # Exit loop prematurely. $_ = $_ * 2; } print "Numbers now ",join(", ",@array),"\n";


    -Lee

    "To be civilized is to deny one's nature."
Re: infinite loop on while (@array)
by Fletch (Bishop) on Mar 27, 2002 at 13:52 UTC
    The reason why I'm not using for or foreach is because I need to change the loop control variable...

    foreach my $foo (@bar) {...} works just as while my $baz (@quux) { } does. perldoc perlsyn