-
Notifications
You must be signed in to change notification settings - Fork 27
Improve ergonomics and usefulness of es -e
.
#73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
… catch, complain, and retry); and limit the exit-on-false behavior to only be triggered in the context of %exit-on-false.
This feels like a hack, but it seems to work, and I can't come up with a way to break it right now.
A thought that has just occurred to me, relevant for exception-based exit-on-false: Should false-exiting commands also cause an exception inside an exception handler? For example, if the following script is sourced with
|
Regarding your last suggestion, i would expect anything inside an exception handler that results in a false value to throw another exception when I haven't encountered any trouble yet, but why does a Or am i missing something glaringly obvious as usual? :-P |
Yikes. Though I suppose that things like
still work? This feels to me like a tradeoff between "more-surprising and more-useful" behavior and "less-surprising and less-useful" behavior. It's hard for me to judge the tradeoff without some actual experience. So I guess initially I'd say let's go with the less-surprising behavior, and if it ends up burdensome in practice, it can be revisited later.
You're missing nothing at all, and I actually prefer a complain-and-retry behavior in |
This reverts commit a4f3b6d.
I only just got this (somehow I don't remember reading it at all before). You're 100% right, I missed that case. Though now that I look at it, I'm not entirely sure what the point of the |
This causes %exit-on-false, as part of %dispatch, to be the actual trigger for the exit-on-false behavior. The implementation context strongly implies that the current behavior is a bug. (Why would we use %exit-on-false, whose only job is to set eval_exitonfalse to 1, and also just leave eval_exitonfalse as 1 ourselves?) This also makes using `es -e` with any kind of overriden REPL much easier, because %prompt and other REPL hooks can no longer trigger the exit-on-false behavior. This is one part of wryun#73, but because this part is almost definitely just a bug, while the rest is more about design improvements, I am merging this part more unilaterally.
This causes %exit-on-false, as part of %dispatch, to be the actual trigger for the exit-on-false behavior. The implementation context strongly implies that the current behavior is a bug. (Why would we use %exit-on-false, whose only job is to set eval_exitonfalse to 1, and also just leave eval_exitonfalse as 1 ourselves?) This also makes using `es -e` with any kind of overriden REPL much easier, because %prompt and other REPL hooks can no longer trigger the exit-on-false behavior. This is one part of #73, but because this part is almost definitely just a bug, while the rest is more about design improvements, I am merging this part more unilaterally.
Now this PR also fixes #176. Essentially we no longer "turn off"
you no longer have whether you call
or
(note that in the current shell at HEAD, the body of that It also makes it so these two now, consistently, don't stop on false:
|
Okay, actually, I think this requires a little more thought. Note that I still like most of the proposed setup, but it doesn't resolve every edge case quite as cleanly as I'd prefer. For example, take the following little script:
Of course, the right output for this script without
I assert that the right output with
-- that is, the Now here's where it gets funky. This fork's es, run with
Infinite loop is not very good. What's even weirder is that es at HEAD with
The Both of these wrong behaviors come down to how
While running, My initial thought was, okay, let's make So this is all kind of funky. And I think the question of "so what's the point of keeping Yes, that would be nice. And that's basically what elvish does; they throw out "exit statuses" in its Unix-y concept entirely and make it so that external binaries trigger an exception if they don't exit 0, and anything built-in also just throws an exception on failure. But es isn't quite so aggressive in forsaking the Unix model, and unless we decide to be, we need to support "exceptions on false" ( I think that's about as good as we can get. |
Actually, there may be a different way to do it, where only |
This pull request is meant to improve the usefulness of es'
-e
flag. It does a few things:This makes it so that exits-on-false only occur when
$&exitonfalse
is actually in the call stack. With this, REPL code, and functions called from the REPL like%parse
or%write-history
, can't cause the shell to implode, and so are much easier to write.result <={var = value}
).The implementation seems a little sketchy to me, but as far as I have been able to test, it works. Before this PR, every one of the following lines causes the shell to exit; with it, none of them do.
Instead of just calling
exit(2)
, throw afalse
exception along with the triggering value. I strongly feel that using an exception is the Right Thing:most other ways to cause the shell to exit do so via exceptions -- including the
exit
command itself! It is unpleasantly surprising to lack the ability to handle and clean up after errors just for this.exit-on-false is essentially a crappy imitation of exceptions in shells that lack them. Es actually has exceptions, so it should use them for this like it does for internal errors, signals, and the like. Exceptions are a far more powerful mechanism for error handling than just killing the process.
the "nuclear option" of exiting on false requires that when commands are run inside constructs that actually want to use their return values, like
if
or<=
, the exit-on-false behavior has to be "switched off" in order that the shell doesn't just go poof, which leads to confusing behavior; see (More) issues withes -e
#176. Exceptions, on the other hand, can simply be handled by theif
and<=
constructs directly, such that actually generating the exit-on-false exceptions doesn't need to be "toggled" off and on during the execution of a script.I picked a new exception
false
because it enablesif
and<=
to catch these particular exceptions without also messing witherror
s or any other exceptions.I would rename
%exit-on-false
and$&exitonfalse
to%throw-on-false
and$&throwonfalse
if not for maintaining backwards compatibility.If the user doesn't go out of their way catch
false
in a script, then the shell will quietly exit. In an interactive context...%interactive-loop
catches thefalse
exception, complains, and then re-prompts.This is a fair bit friendlier than silently exiting -- not that it's very typical to use
-e
for an interactive session.