Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.unix.shell > #4378
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Newsgroups | comp.unix.shell |
| Subject | Re: Why 'break' even has effects outside of its function? |
| Date | 2012-03-07 09:39 +0000 |
| Organization | Aioe.org NNTP Server |
| Message-ID | <20120307010429.677@kylheku.com> (permalink) |
| References | <jj1t5r$nsj$1@wangcong.dont-email.me> <jj309m$7d9$1@news.m-online.net> <jj3du8$jqm$1@speranza.aioe.org> <20120306215813.85@kylheku.com> <jj77u1$jn3$1@speranza.aioe.org> |
On 2012-03-07, Alan Curry <pacman@kosh.dhis.org> wrote:
> In article <20120306215813.85@kylheku.com>,
> Kaz Kylheku <kaz@kylheku.com> wrote:
>>On 2012-03-05, Alan Curry <pacman@kosh.dhis.org> wrote:
>>> Right, but the second parsing is done on the eval'ed command line later, and
>>> the parsing of the loop is not in progress at the same time, so it's weird to
>>> think of the loop as "lexically enclosing" the second parse. It's more
>>> natural (for me at least) that eval should create a new top-level lexical
>>> environment.
>>
> [...]
>>
>>Anyway, the standard shell language does not have lexical /anything/.
>>Just top level functions and variables.
>
> The shell itself contains a parser for the language. An obvious
> implementation would create a new one of those, with no way of knowing
> whether it's inside a loop in the outer execution environment, and thus no
> way to influence an outer loop's execution.
>
>>
>>For instance you can write a function which accepts a variable
>>name (for a variable in the calling environment) and can change its value.
>
> Having access to variables is nowhere near as deep a relationship as having
> access to the execution control stack that keps track loops currently in
> progress!
It is exactly the same thing. The control stack contains variables that
keep track of this.
>
>>In Bash, your eval'ed code can not only refer to the variable whose name
>>was passed in, but also to the local variables in the function.
>
> Global variables are accessible everywhere, including functions and evals.
> That doesn't seem like a big deal to me.
>
>>
>>You can write a function which controls the evaluation of syntax
>>that is passed in:
>
> This should be good...
>
>>
>>dotimes ()
>>{
>> local __count_var=$1
>> local __max_count=$2
>> local __count=0
>>
>> shift; shift;
>>
>> while [ $__count -lt $__max_count ] ; do
>> eval $__count_var=\$__count;
>
> I think that would be just as good without the backslash.
Yes, but only because we control __count and we know that __count contains a
number. A double evaluation of a number just yields that number.
In the general case, we want that dollar sign to survive into the eval, so the
eval will properly evaluate $__count, expanding just once.
> And indirect
> assignments are surely one of the most common uses of eval, so not
> surprising.
>
>> eval "$@"
>
> Whether this is a spooky eval or not depends on what the caller put in it...
Not really. Unless the caller knows about __count_var and __count,
the eval will behave in an expected way.
>> __count=$(( __count + 1 ))
>> done
>>}
>>
>>dotimes x 10 'printf "x = %d\n" $x'
>
> And this caller doesn't put anything interesting there. This works perfectly
> in pdksh, which doesn't support "eval break".
Thus, it is inconsistent.
> If you try
>
> dotimes x 10 'printf "x = %d\n" $x;break'
>
> then most shells just print "x = 0" and quit,
But that is a feature! break bails out of dotimes properly. dotimes is a wrapper
around a while loop.
>>Bash does the "right thing" by conforming to the expectations of shell coders,
>>The alternative is to die with an error, which is nonproductive.
>
> pdksh does the "right thing" by telling the coder he's nuts.
Which is out of place in a language that allows nutty eval hacks.
Bash is consistent.
>>
>>That naive behavior is not so naive: it lets you do things that are not
>>possible otherwise.
>>
>>Now here is my point. Think about this. Suppose the above "eval $br" were to
>>die with error like "bash: break: only meaningful in a `for', `while', or
>
> ...like pdksh's error message but more verbose....
>
>>`until' loop". Given that we can write the dotimes function above, with
>>the crazy eval hacks that work, and that we have to hide our local variables
>>with underscores, etc, don't you think that this diagnostic would be
>>/laughably/ inconsistent?
>
> Me and pdksh don't think so, since we see looping control structures as
> super-low-level stuff that should resolve at parse time, and shell variables
> as a simple global mapping of strings to other strings.
That is laughably inconsistent. Part of the language has delusions of grandeur
about becoming a compiled language one day, and part of the language is
a dynamically scoped hack.
Simple global mapping? Are there no locals then?
>
>>
>>> Some of us just think of "break" as being bound to the enclosing "while" in
>>> exactly the same syntactic manner as the "done" that ends it.
>>
>>done is just punctuation, like a closing parenthesis. break has semantics of
>>its own.
>>
>>Moreover, you do not necessarily know, statically, where it goes. Remember, it
>>takes an argument: break $run_time_value .
>
> Oh hell, that seals it. All the previous examples are only slightly spooky.
> That's like a computed goto.
Precisely: with N nestings, there are N possible target points, selected by number.
Nothing "like" about it.
> No... it's more than that. Combined with the
> ability to break out of a function, you can't even know how many functions
> you'll be prematurely remotely terminating. It's pure evil... it's LONGJMP!
It would be even more like longjmp if it used named blocks instead.
break main_event_loop_way_up_high
> The Bourne shell has been hiding a longjmp equivalent all this time. Must
> wash hands... can't get clean...
But bash has the internal unwind-protect to undo the local variables, whereas
longjmp doesn't clean up (unless you wrap some functionality around it and use
only the disciplined interface).
# global x
x=42
func()
{
local x=0
break;
}
while true; do
func
done
echo $x
Output:
42
longjmp, but with proper unwinding of the dynamic scope which restores the
global value of x.
Man is this break hack ever well-supported, wouldn't you say. :)
I'd be curious what happens if you step through this in the bash debugger, bashdb.
Will it preserve the semantics? Ha.
Back to comp.unix.shell | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Why 'break' even has effects outside of its function? Cong Wang <xiyou.wangcong@gmail.com> - 2012-03-05 08:23 +0000
Re: Why 'break' even has effects outside of its function? Lew Pitcher <lpitcher@teksavvy.com> - 2012-03-05 01:03 -0800
Re: Why 'break' even has effects outside of its function? Cong Wang <xiyou.wangcong@gmail.com> - 2012-03-05 09:42 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-05 13:59 +0000
Re: Why 'break' even has effects outside of its function? Janis Papanagnou <janis_papanagnou@hotmail.com> - 2012-03-05 15:40 +0100
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-05 15:18 +0000
Re: Why 'break' even has effects outside of its function? "Ed Morton" <mortonspam@gmail.com> - 2012-03-05 16:03 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-05 16:37 +0000
Re: Why 'break' even has effects outside of its function? "Ed Morton" <mortonspam@gmail.com> - 2012-03-05 17:49 +0000
Re: Why 'break' even has effects outside of its function? gazelle@shell.xmission.com (Kenny McCormack) - 2012-03-05 18:02 +0000
Re: Why 'break' even has effects outside of its function? Ed Morton <mortonspam@gmail.com> - 2012-03-05 17:57 -0600
Re: Why 'break' even has effects outside of its function? Janis Papanagnou <janis_papanagnou@hotmail.com> - 2012-03-05 19:22 +0100
Re: Why 'break' even has effects outside of its function? pacman@kosh.dhis.org (Alan Curry) - 2012-03-05 22:15 +0000
Re: Why 'break' even has effects outside of its function? Janis Papanagnou <janis_papanagnou@hotmail.com> - 2012-03-06 12:04 +0100
Re: Why 'break' even has effects outside of its function? pacman@kosh.dhis.org (Alan Curry) - 2012-03-06 23:10 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-07 05:58 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-07 05:58 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-07 07:25 +0000
Re: Why 'break' even has effects outside of its function? pacman@kosh.dhis.org (Alan Curry) - 2012-03-07 08:57 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-07 09:39 +0000
Re: Why 'break' even has effects outside of its function? pacman@kosh.dhis.org (Alan Curry) - 2012-03-08 01:28 +0000
Re: Why 'break' even has effects outside of its function? Sven Mascheck <mascheck@email.invalid> - 2012-03-13 22:50 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-13 23:00 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-14 05:59 +0000
Re: Why 'break' even has effects outside of its function? Kaz Kylheku <kaz@kylheku.com> - 2012-03-07 05:48 +0000
Re: Why 'break' even has effects outside of its function? Barry Margolin <barmar@alum.mit.edu> - 2012-03-05 13:29 -0500
csiph-web