Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Issues with named references
On Thu, May 1, 2025 at 6:32 PM Philippe Altherr
<philippe.altherr@xxxxxxxxx> wrote:
>
> An important expectation that I have for named references is that once a named reference is successfully resolved, it keeps referring to the same variable for the rest of its lifetime.
This would break one of the defined use cases for a named reference:
typeset -n ref
x=X y=Y z=Z
for ref in x y z; do print $ref; done
There, $ref becomes a stand-in for each of $x $y and $z in turn.
> Section 14.3.2 states instead that "named references always expand parameters at the scope in which rname existed when ‘typeset -n’ was called". For a declaration like "typeset -n pname=rname" where "rname" already exists, the two specifications are equivalent. However, the description of "typedef" states "The second parameter (i.e., rname) need not exist at the time the reference is created" and section 15.5 states "The first non-empty assignment to pname initializes the reference", which suggests that "typedef -n pname" with no "rname" are allowed.
That last is in fact intentional, see example above, although that's
not the only possible use case.
> These two features are both incompatible with the statement of section 14.3.2 (it's unspecified how such named references are supposed to be resolved).
I'm not sure why you find this to be unspecified. If foo is a named
reference, then first $foo is resolved to its value, and then that
value is evaluated as a parameter substitution. This is supposed to
always the case, except where the -u flag first moves the starting
point up one scope.
typeset -n foo
print $foo # equivalent to ${:-}, the empty parameter name
typeset -n foo=notyetdefined
print $foo # equivalent to $notyetdefined, the empty result
> My tests show that they both enable the creation of dangling references, which lead to previously successfully resolved named references becoming invalid again and being rebound
That's the way dynamic scoping works, yes. An assignment from an
inner scope to a variable declared in an outer scope changes the value
in the outer scope. Because (as you already noted) a reference in an
outer scope cannot continue to refer to a parameter in a finished
scope, the only correct behavior upon next use of that reference is to
re-evaluate it in the current scope.
Your test cases have revealed some instances where this goes wrong; in
particular named-references-with-u-flag.zsh works as you expect if
workers/53431 is backed out. I'll have to look more closely at
delayed-named-reference-initialization.zsh because something
unintended is happening after the f5 scope ends. I believe
dangling-references.zsh is working as it should.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author