Hi Cynthia, thank you for your reply. 2022年10月8日(土) 17:26 Cynthia Coan <cynt...@coan.dev>: > > I agree the proper implementation of `defer' by the RETURN trap could > > be tricky (as described in "notes" in my previous reply), but it's > > definitely not as hard as you initially posted (one 12-line function > > vs 244-line defer.sh). > > [...] the reason it implements the "function local" state > itself is because for quickness of a PoC it was copied from an "error > mode" example
(This is just a side note about `local -' but unrelated to the main discussion): I didn't mention it because I thought `set -e' is merely an example to demonstrate the behavior of `defer', but if the handling of `set -e' is one of the main motivations for requesting `defer', I suggest trying Bash 4.4's `local -', which localizes the shell-option changes within the function. If the function doesn't want to change the shell option of the caller, it can just declare `local -' before changing any shell options. [ It is unavailable in Bash 4.3 or below, but the suggested `defer' builtin would neither be available in older versions of Bash, so we can forget about the support of `local -' of older Bash in the discussion of the new feature. ] > which does need to implement function local checks > itself (with functrace), as if the function "sets error mode", and > than calls another function which changes the error mode not through a > wrapper you'd be in the wrong state for the rest of the function. So > you always need to check where you are. I think you might be caring about the cases the callee changes the error mode without restoring it, but I would say that restoring the error mode to the original is the responsibility of the callee function, but it's not what the caller or the entire execution system of Bash should take care. Also, how to distinguish them from the functions that want to intensionally change the error mode of outer/global scope (such as functions similar to `__{push,pop}_error_stack' in other codebases)? Here, I still think we do not need to re-implement the function-local traps other than the already built-in one even for the `set -e' handling. > I'd prefer we don't focus on any particular implementations, or how > many lines they end up being. Obviously, the number of lines itself is not important. I mentioned the number of lines because you seemed to present the idea that "the implementation can be harder than they need to be" mentioning the original email [2]. [2] https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00036.html >>> In fact some of the things you mentioned you can do today, are also >>> outlined in the original email as things that can be "harder than they >>> need to be" But I don't think it is hard to implement it in a shell script as said in the original email, so I just used the number of lines as an ``approximate'' measure of how hard the code is. If both codes had similar numbers of lines, it wouldn't correctly compare the actual complexity of the codes as you think, but I think the number of about 10 lines is clear to show that the implementation is not that hard (as far as one understands the usage of the RETURN trap) compared to what the original email seemed to convince us with the link to 244 lines of code (regardless of the intention). > I'm not saying > defer necessarily meets the same bar as usefulness, but I think it'd > be wrong to dismiss new features just because they can be accomplished > today, with relatively few lines. In my point of view, the suggested "new" feature is *already implemented in Bash as the RETURN trap*, and there is no reason to add the same feature twice. These "relatively few lines" (including `declare -ft' and the FUNCNAME check) are just needed to adjust the usage to your taste as the wrapper `defer'. If we do not use `defer', we could naturally write it like eval "original=($(trap -p RETURN))" trap "trap - RETURN;xxxx;${original[2]}" RETURN If `trap -P' suggested by Oğuz would be supported, it can even be simplified as trap "trap - RETURN;xxxx;$(trap -P RETURN)" RETURN The remaining complication is actually caused by the lack of support for the multiple trap handlers and is unrelated to `defer'. Of course, if one wants to use the above idiom multiple times, it may not be useful to write it every time. In that case, one can define a function. If it needed to implement the essential parts of the processing as in defer.sh, it might have been better implemented as a built-in feature, but I don't think the wrapper of the above one or two lines should be a separate builtin command. A shell function is sufficient. > Interesting, is this purely about lines of code? Of course, no! See the above response about the number of lines. > On the traps append/prepend point I will have to > do some thinking on that, I'll take the weekend/beginning of the week > to think of what I can, but if someone else has ideas I would love to > hear those too. I think this is a more general topic than defer, so I think you can create a separate thread for it. Also, I guess more people are interested in the multiple trap handlers compared to `defer'. -- Koichi