Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: "break" and functions
- X-seq: zsh-workers 52852
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: Re: "break" and functions
- Date: Fri, 29 Mar 2024 11:51:03 -0700
- Archived-at: <https://zsh.org/workers/52852>
- In-reply-to: <43539-1711733926.063834@011r.oEGd.QZp_>
- List-id: <zsh-workers.zsh.org>
- References: <CAH+w=7bb9BKUCvqCb=A-Qw36+HVn-NszP2DfQeXsYmKs-HVWFg@mail.gmail.com> <43539-1711733926.063834@011r.oEGd.QZp_>
On Fri, Mar 29, 2024 at 10:38 AM Oliver Kiddle <opk@xxxxxxx> wrote:
>
> My expectation would have been for either an error message saying
> break: not in while, until, select, or repeat loop`
> or that because the break is run before the builtin that the builtin
> would never get to run.
The latter was my expectation; I think the break is inside the loop.
Skipping ahead:
> It also rather surprises me that the break here even works:
>
> br() { break }
> while : ; do
> br
> done
% setopt localloops
% br() { break }
% repeat 3 br
zsh: `break' active at end of function scope
zsh: `break' active at end of function scope
zsh: `break' active at end of function scope
% unsetopt localloops
% repeat 3 br
%
> But the implementation of break is just putting
> a value in the breaks integer variable so I guess that variable isn't
> checked until after the builtin is run.
Right; since the break occurs in prefork() we're already deeper in the
execXXX() call stack than anywhere the variable is checked. The
function call re-enters that stack closer to the top, and finds the
setting.
> The anonymous function is
> perhaps a two-stage process for defining and then running. Note:
> while :; do; () { echo hello } > ${|REPLY=x;break}; done
> creates an empty file named x.
Again, prefork() ... the redirections also occur before breaks is
checked. Although this:
echo xx > ${|REPLY=x;exit}
does bail out before completing the redirect, whereas this:
echo xx > ${|REPLY=x;return}
does not.
> When suggesting the test, the exact behaviour was not something I cared
> strongly about provided it wasn't seg fault, infinite loop or similar.
Yes, I understand. I considered testing this way for future-proofing:
repeat 3 V=${|REPLY=x; break}
print $V
I ended up deciding that it was reasonable to leave the "echo ${|...}"
as an ad-hoc regression test in the event builtins do start
"break"-ing.
> In the case of
> repeat 3 print c*(oe:'break':)
> it might be a useful feature if break applied to the internal loop over
> globbed files causing print to run but only with those files that were
> matched so far.
IIRC the entire glob loop finishes and then any (e) actions are
applied to the resulting list. So "matched so far" is not well
defined. I believe the only way to stop the internal loop "early" is
the (Y) qualifier.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author