Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: for loop question



On Mon, Nov 3, 2014 at 3:22 AM, Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
> On 11/02/2014 05:53 PM, Mikael Magnusson wrote:
>>
>> We might want to avoid using obscure mixes of the discouraged alternate
>> syntax with syntax that depends on short_loops being set, when helping
>> people who are asking questions about basic syntax. :)
>
> It does get a bit overwhelming.  However, when I poke at the syntax by
> asking 'why can't we ...' sorts of questions, I expect to more or less have
> my fuses blown ;-)  Still, any sort of heads up about what is considered
> proper vs. what is considered discouraged will be most appropriate.

If you look up the section "Complex Commands" in the manpage, they're
all listed fairly well explained. The section after that is called
"Alternate Forms for Complex Commands" and lists some syntax that is
convenient interactively but not super encouraged. Using any syntax
that depends on SHORT_LOOPS being set will of course not work in any
other shell, and also has the downside that making a small mistake
will usually still parse but do something entirely unexpected. I'm a
bit more opposed to SHORT_LOOPS than others here, but when I disabled
the option, I immediately found like 5 bugs in the completion system
so I think I'm at least somewhat justified :). The whole point of it
is just to not have to write do; done, but it causes so many bugs and
confusion.

As to the for loop, it has two different forms. They're almost so
different you could say the only thing they have in common is the word
"for" :). One is
for some variables in list of values; do
  list; of; commands using $some $variables
done
Think of that as a foreach loop. The other form is
for (( i=0; i<10; i++ )); do
  list; of; commands using $i
done
This form is exclusively for math expressions, you can't just stick
arbitrary commands in there. If you want that, just use a while loop.
commands to initialize state
while my condition; do
  stuff
  here
  increment iterator or whatever
done
because as you saw, stuffing it all into the for line would just get
really ugly. And you want the foreach form for your initial example as
Stephane said, there is no need to iterate over the index unless you
have a veeery large array, and then it will already be very slow
anyway.

As a side note, if you ever want a do-while loop instead of a regular
while loop, the trick is
while just put the whole body;
      of the loop here instead;
      and the last command is;
      the terminating condition; do done

-- 
Mikael Magnusson



Messages sorted by: Reverse Date, Date, Thread, Author