[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Why should `break' and `continue' in functions not break loops runni

From: Oğuz
Subject: Re: Why should `break' and `continue' in functions not break loops running outside of the function?
Date: Sat, 30 Oct 2021 20:45:05 +0300

On Sat, Oct 30, 2021 at 7:07 PM Robert Elz <kre@munnari.oz.au> wrote:
> What POSIX says about this (which you probably know already) is:
>         A loop shall enclose a break or continue command if the loop
>         lexically encloses the command. A loop lexically encloses a
>         break or continue command if the command is:
> [and just paraphrasing the conditions]
>         - same exxecution environment (ie: not in a subshell)
>         - inside a compound list associated with a loop (including
>                 the test list for while/until)
>         - not in the body of a function ...
> (more or less the obvious useful definition of lexically enclosing).
> That is the case in which break & continue are required to work.
> It goes on to say:
>         If n is greater than the number of lexically enclosing loops
>         and there is a non-lexically enclosing loop in progress in the
>         same execution environment as the break or continue command, it is
>         unspecified whether that loop encloses the command.
> In your example, the number of lexically enclosing loops is 0, 'n' is 1,
> so the shell is allowed to break from the loop, but not required to.

Yes, I read all about this, thanks for the summary.

> Or in other words, you should not write code like that, because it
> is not guaranteed to work.

Pity. But at least for now, (in bash, not other shells) I can place
the function call between `shopt -s compat43' and `shopt -u compat43'
and have the behavior I want without side effects (I believe).

> oguzismailuysal@gmail.com said:
>    | `break' is not a keyword in the shell, but a special command.
> That's true.   However, 99% of script writers don't see it that way,
> they believe it is just like "if" or "while" or "done" or "return".
> That's why the "This is counterintuitive." I would guess - in most
> cases, the issue isn't quite like yours, but more like
>         f() {
>                 for x in a b c; do
>                         for y in 1 2 3; do
>                                 case "$x$y" in
>                                 (b3)    break;;
>                                 (a2)    continue 2;;
>                                 (c1)    break 3;;
>                                 esac
>                         done
>                 done
>         }
> and then called something like
>         for i in 1 2 3 4 5 6
>         do
>                 echo $i; f
>         done
> and people wonder why that loop never iterates the 2nd time (prints just 1).
> All this because the script author probably thought that they were
> writing C, and the b3 break is for the case statement, a2 continue
> is the y loop, and c1 break the x loop...
> They can be taught that that's wrong, break/continue do nothing for
> case statements, and don't count them - but they simply refuse to believe
> that whatever happens inside the function should affect the caller's
> flow - an error from the "break 3" is something they can understand,
> as is just ignoring the "overflow", but not more than that.

Yeah. Not about break/continue, but I met many complaining about how
there should be spaces around `[' and `]', how `if [ grep foo file ]
...' never reaches the else part, etc. and it's all tiresome.
Thankfully I'm not writing a shell.

> For people who don't believe that all programming languages should work
> the same way (usually the same way as the one they learned first) this
> isn't necessarily as important - but that's a tiny majority of people.
> kre
> ps: the NetBSD shell continues to work the way that you want, and does
> so by deliberate choice - our test suite has a whole stack of tests to
> make sure this continues to all work "correctly" (doesn't accidentally
> get changed).

I know, it's great. Though I still couldn't figure out how to have a
command run on login and it drives me mad.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]