Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: nameref binding not finding calling-scope vars?



On Wed, Apr 2, 2025 at 7:36 PM Phil Pennock
<zsh-workers+phil.pennock@xxxxxxxxxxxx> wrote:
>
> However, if I use `setopt warn_create_global` then the version where
> inner() uses `typeset -ga` is the only one which does not issue a
> warning.
>
>  A: inner() { local -n var="${1:?}"; var=(alpha beta gamma); }
>  B: inner() { local -n var="${1:?}"; typeset -ga var=(alpha beta gamma); }
>  C: inner() { local -un var="${1:?}"; var=(alpha beta gamma); }
>
> Is my thinking here Wrong?  It seems like `-un` is being very explicit
> that the value should be found in the calling scope

But the warning only occurs when the parameter name is NOT found in
the calling scope.

> much like the
> implicit behaviour of -g when using the nameref, so there's no need for
> the warning.

The difference is that "typeset -g" is explicitly creating a name,
potentially in the calling scope, whereas "local -nu" is searching for
a name in the calling scope.  The creating part is a separate
operation.  Have a look at the attached three variations of calling
your three examples.

The warning appears in the first set (A,C) and in the second set
(Ax,Cx).  In those sets the variable created is a global.  In the
third set where the variable is predeclared local, there's no warning.
There would also be no warning if the variable were predeclared global
(because then nothing is created).

Adding -u to the named reference declaration doesn't tell the calling
scope anything about the scope where the assignment actually takes
effect.
setopt warncreateglobal

print A
inner() { local -n var="${1:?}"; var=(alpha beta gamma); }
inner A
typeset -p A
print B
inner() { local -n var="${1:?}"; typeset -ga var=(alpha beta gamma); }
inner B
typeset -p B
print C
inner() { local -un var="${1:?}"; var=(alpha beta gamma); }
inner C
typeset -p C

outer() { inner $1; typeset -p $1 }
print Ax
inner() { local -n var="${1:?}"; var=(alpha beta gamma); }
outer Ax
print Bx
inner() { local -n var="${1:?}"; typeset -ga var=(alpha beta gamma); }
outer Bx
print Cx
inner() { local -un var="${1:?}"; var=(alpha beta gamma); }
outer Cx

outer() { local -a $1; inner $1; typeset -p $1 }
print Az
inner() { local -n var="${1:?}"; var=(alpha beta gamma); }
outer Az
print Bz
inner() { local -n var="${1:?}"; typeset -ga var=(alpha beta gamma); }
outer Bz
print Cz
inner() { local -un var="${1:?}"; var=(alpha beta gamma); }
outer Cz


Messages sorted by: Reverse Date, Date, Thread, Author