2025年9月3日(水) 1:21 Martin D Kealey <mar...@kurahaupo.gen.nz>: > I really like this approach, but I suspect it will lead to a need > for something akin to Perl's "use" or "BEGIN" keywords to execute > code as soon as they're fully parsed, even if the encoding block > hasn't finished parsing. > > Then we could write something like this: > > >>MyLib.bash<< > shopt -s lexical > myfunc() { > BEGIN { shopt -s extglob; } > echo *(.)foo # safe because « shopt -s extglob » runs before parsing this > line > }
Hmm, it seems different from what I have in my mind. What is the "lexical" option in the above example? Do you mean by the "lexical" option a feature to use the lexical scoping for existing shell options (including `extglob')? I didn't mean to switch the scoping of existing shell options, but I meant that the scoping of new language-level options should be *fixed* to lexical scoping. Suppose we want to add a hypothetical option to use PCRE for regex matching in [[ str =~ regex ]], we add an option `shopt -s parse_regex_pcre' (which doesn't affect the scoping of existing shell options). (In case, I don't suggest adding the built-in support for PCRE, but it's just an example.) Since how this new type of options is applied is different from the traditional shopt options, it might deserve a new builtin (other than `shopt' or `set'), but it is generally avoided to add a new reserved word. Practically, while still using `shopt', we can clarify that it is applied at the parsing time by naming an option with a specific prefix (such as `parse_' and `lex_'). # MyLib.bash shopt -s parse_regex_pcre myfunc() { [[ foo =~ bar ]] } > Admittedly extglob isn't an ideal example, since in practice one > would just set it at the file level, but I'm trying to illustrate > how it could change a setting during parsing. My idea is to force a consistent behavior within a file, so that the "language-level" options should be set up at the top level around the beginning of the file, and all loops and functions in the file should be written using the same "verson of Bash language" (defined by a set of language-level options)..Although it is still technically possible to switch `shopt -s/-u parse_regex_pcre' between function definitions so that two functions use different rules, I don't think we want to use two different behaviors within a single function by switching the option in the middle of parsing a function. If a shell option needs to be switched within a single function, it implies that the option provides two distinct features (where the result with one side of the option cannot be easily achieved with the other side of the option) and a function wants to use both features. In this case, the two distinct features shouldn't be provided through a shell option, but they should have distinct ways to call. > Question: if file A sources for B, and file B sources file C, but > only file B indicates it expects lexical option scoping, should file > A and file C see each other's changes? I think this is based on your assumption on `shopt -s lexical'. I didn't intend an option like `lexical', and I don't think it is good to provide a way to switch the scoping of options. It introduces unnecessary confusions. New language-level options should *always* be applied at the parsing time, and existing language-level options should keep its current behavior for backward compatibility. It's too late to change existing ones. If a lexically scoped version is needed, it should be given a new name like « shopt -s parse_extglob », though how it should interact with `extglob' would require further consideration. > While we're at it, please can we have lexically scopes variables in > functions? It is a different topic, and I don't think it is relevant to the present discusssion. Considering the case where we want to use both types of variables in a single function, I don't think it should be introduced through a shell option. As I wrote in a relevant thread in the past, I think lexically-scoped variables should be provided through a distinct way of declaration such as `local -l var' (as done in Perl with `my'). > Maybe « function foo -o compat=60 -o extglob -o nullglob … { …; } »? With that syntax, Zsh defines multiple functions of the same content, which can be observed with the following command: $ zsh -c 'function foo -o compat=60 -o extglob -o nullglob ... { echo; }; declare -f' I'm not sure if we want a similar feature in the future, but at least, I think we want to avoid a confusing syntax as much as possible. >> ». Note that in this example, one needs to explicitly unset an option >> `zzz' by `+o zzz' because `zzz' might be turned on in the context >> where `eval' is performed. > > With « -o compat=60 » in my example we then only need a list of > options that don't match, rather than all of them. That seems a valid solution. -- Koichi