2024-11-02 05:55:52 +0000, Andrew via austin-group-l at The Open Group: > I see oft repeated that shells presently use the keyword > `local` with varying semantics, as if anyone needed to be > constantly reminded of this trivial fact.
For reference, see https://unix.stackexchange.com/questions/493729/list-of-shells-that-support-local-keyword-for-defining-local-variables/493743#493743 for an attempt at giving a state of the art in that regard. > So what? That is not a blocker. Arrive at a consensus on a > useful lowest common denominator set of semantics for function > scoped variables, and select a different keyword than `local`. > I propose `let`. [...] "let" is already a builtin of ksh (on which the specification of sh is based), zsh and bash for something unrelated, so wouldn't be an option. Now, local scope in shells has been discussed extensively over decades here, and there has been some progress, and I feel there should be path for agreement on something usable. David Korn (at the time he was still active) had already agreed to do dynamic scoping for "local" (as opposed to "typeset") in ksh (and I beleive there is code already for that in ksh93, even if that's maybe in the (now abandoned) ksh93v- beta version) kre had suggested introducing -N (new) vs -I (inherit) options to "local" (chosen not to conflict with any existing option in any shell at the time) to address one of the major differences in semantic between shells and he implemented it in NetBSD sh (https://man.netbsd.org/sh.1); bash also added a localvar_inherit option for that; and localvar_unset for some other difference. It seems an avenue could be to specify "local" when -I/-N is used and have everyone agree on the semantic there. I'd suggest: - local -I [-x] [-r] [--] var[=value] [var2[=value]...] inherit value and attributes (all of which can be overriden on the command line) local -N [-x] [-r] [--] var[=value] [var2[=value]...] creates unset with no value other than those specified on the command line if any. anything else unspecified - dynamic (not static) scoping. - dual keyword/builtin like for export, that is var=... are parsed as assignment as long as "local" is a literal whole unquoted word and var= is literal and unquoted. Same rules as for export about order of assignment and combining with redirections, etc. - unspecified what happens if function is called as var=value myfunc and myfunc does "local var" (same for var=value command* eval myfunc and other variants). - unset removes value and attributes (not read-only) but keeps the variable local even if called within a child function (like with the localvar_unset option enabled in bash) - still can't unset a readonly variable, whether it's been made local or not but - behaviour unspecified when using local on a variable that was read-only in a parent scope. I would personally allow it (same reason as restricted shell not specified by POSIX; readonly is more useful as a development tool than as a security measure wahich would be too weak), but I know that's contentious. - when calling "local" again on a variable already made local in the current scope, with -N, work like unset (but still allowing -x, -r, =value to set value and attribute) and with -I, no-op other than -x, -r, =value if any being applied. - we could specify the Almquist shell's "local -" (now also in bash for its set of options managed by "set") as "local -I -" (to make option settings local, as ksh88 does by default, ksh93 only in the functions declared with the function f {} syntax and zsh with set -o localoptions), and "local -N -" to have a default set of option locally (like zsh's emulate -L sh) What do you think? -- Stephane
