Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: while loop grammar question
On Sun, Dec 8, 2024, at 9:25 AM, Ray Andrews wrote:
> Yikes, gotchas within gotchas. I expect something so fundamental is
> pretty deeply coded so might have to be lived with.
I would be surprised if there were many users reliant on this
optional-loop-body behavior.
> Even given your
> explanations above, it seems strange that the 'while' loop loops -- it
> knows it's a loop but it doesn't understand it's own break condition.
It does understand its own break condition. The issue is that the
break condition -- e.g., the command whose exit status matters --
is not where you think it is. In a nutshell, this:
while ((0)) {
print foo
}
# ...
is equivalent to:
while
((0))
do
print foo
done
# ...
but this:
while ((0))
{
print foo
}
# ...
effectively works like:
while
((0))
{
print foo
}
# ...
do
:
done
(I'm using "# ..." to represent any subsequent commands.)
Remember that the test is a list of zero or more commands. So the
last command of the script, whatever it is, controls the loop.
> So it is critical where the left brace is?
Yes. If the left brace is on its own line, then it begins a { ... }
grouping command that is part of the test. Consider that this is
valid (if silly):
x=0
while ((++x))
{
print testing
}
[[ x -le 3 ]]
do
print $x
done
On the other hand, this is not valid:
((++x)) {
print testing
}
which is why it could be repurposed for the short commands.
> As usual I'm thinking in C here.
An understandable impulse but one that does not serve you well when
thinking about shell scripting grammar.
> So what would be the hygienic form? Stick with 'do/done' all the
> time?
Yes. It's predictable and largely portable (for those who care
about that, like I do).
> I'd prefer it throw an error consistently rather than accept the
> 'for' form above, which I use all the time. At least I'd expect 'for'
> and 'while' to have exactly the same grammar.
The difference is that "while" is followed by a list of arbitrary
commands that can be separated by LFs (for the short form, only the
final one has to be something like ((...)) or [[...]]). With an
arithmetic "for" loop, the ((...)) construct is actually part of
the syntax, so there's no confusion about where the loop body begins.
--
vq
Messages sorted by:
Reverse Date,
Date,
Thread,
Author