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

Re: [BUG & tentative PATCH] Invalid call to upscope in createparam



On Mon, Jun 2, 2025 at 2:01 PM Philippe Altherr
<philippe.altherr@xxxxxxxxx> wrote:
>>
>> But that's exactly what's not supposed to happen.  "typeset -nu"
>> references are allowed to create globals, "typeset -n" references are
>> not (they can only update what already exists).
>
>
> ?!? Since when is that the case? The current HEAD and the test release both create global variables when assigning to a reference that refers a not-yet-defined variable:

Yes, I think that's actually an inconsistency introduced somewhere
along the way.  At some point it became the case that (where var1 and
var2 do not exist):
  typeset -n ref1=var1 # sets base to global scope
  typeset -n ref2 # sets base to locallevel
  ref2=var2 # does not change base
I think the first was meant to work like the second, not that the
second was meant to work like the first.  None of the tests except
foo=zz tries that ref1=var1 case where var1 hasn't already been
declared.

> There is no explicit documentation of that case but the following statement from section 14.3.2 strongly suggests that for non-upper references assignment to not-yet-defined should work.
>
>> To force a named reference to refer to the outer scope, even if a local has already been declared, add the -u option when declaring the named reference. In this case rname should already exist in the outer scope, otherwise the behavior of assignment through pname is not defined and may change the scope of the reference or fail with a status of 1.

Nothing in those two sentences is meant to apply to the case where -u
is NOT present.  Sorry if the context of "otherwise" was not clear.
"May change the scope" means that the created variable might be a true
global even if the "typeset -nu" declaration is several nested
function calls deep, that is, it won't ever create a local in some
other scope.

> There is also this statement in the same section, which again strongly suggests that for non-subscripted references a variable should be created.
>
>> Unlike ‘(P)’, named references in substitutions that perform assignment, such as ${pname::=word}, do not create new arrays when rname is in the form of an array element or slice and no such array (or associative array) is presently set.

Conversely to the previous sentences you quoted, this has nothing to
do with -u or the scope of pname, and only has to do with the
implementation of ::= (harkening back to the other thread about
subscripting) and of ${(P)...}.  The latter does pure text
replacement, so you can get away with things that don't work if you're
doing actual parameter referencing.

> If non-upper references are not supposed to create variables then I have to ask why. Why should there be such a difference between -n and -nu references?

For the same reason there are differences between "typeset" and "typeset -g".




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