Re: Issue with VAR=foo cmd where VAR is a named reference
Bart Schaefer <[email protected]> Sat, 11 Jul 2026 17:05:22 -0700
| Newsgroups | gmane.comp.shells.zsh.devel |
|---|---|
| Message-ID | <CAH+w=7YjDXOQwnf3F6LW7mPgr5N2T9--WNwy33EBPZ_rry9eCA@mail.gmail.com> |
On Fri, Jul 10, 2026 at 6:39 AM Philippe Altherr <[email protected]> wrote: > > Bart suggested that "var=foo cmd" ought to be the same as running "cmd" in a scope augmented with an exported local "var" parameter: "() { local -x var=foo; cmd }". However, this is incompatible with the current behavior. Indeed, the type of the assigned parameters is preserved. For example, "typeset -i var; var=10+1 printenv var" is equivalent to "typeset -i var; () { local -x -i var=10+1; printenv var }". My proposal is to do the same for references, such that "typeset -n ref=foo; ref=bar cmd" is equivalent to "typeset -n ref=foo; () { local -n ref=bar; cmd }". This seems to me to be in direct conflict with the (reasonable) assertion in workers/54943 that references should not be exported, and also with workers/54948 where you question why inline assignments differ from ALL_EXPORT. The reasoning behind my suggestion (above) was that inline assignments should always yield something that actually goes into the environment: the -x flag in the "as if local -x" is important, and your proposal discards it in the case of references. I'd be more inclined to believe that preservation of (for example) integer-ness is an accident than an intention with respect to inline assignments, that it occurs only because scalar-ness is preserved. Certainly integer-ness etc. is not preserved when the command is external. When the inline assignment is for a parameter declared as an array the type of the assigned parameter is not preserved: % typeset -a foo=(a 2 z) % foo=bar /usr/bin/printenv foo bar % foo=bar printenv foo bar % f() { typeset -p foo; printenv foo } % foo=bar f export foo=bar bar I think this should apply to anything that can't be exported, so if a reference can't be exported then an inline assignment to a reference should temporarily hide it behind a scalar.