Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: ::= didn't respect parameter flags
- X-seq: zsh-workers 54744
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: Mikael Magnusson <mikachu@xxxxxxxxx>
- Cc: zsh-workers@xxxxxxx
- Subject: Re: PATCH: ::= didn't respect parameter flags
- Date: Wed, 10 Jun 2026 14:25:40 -0700
- Arc-authentication-results: i=1; mx.google.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=b9t7v4p5qNNW8NPyJ+WgZizEkD5cc2qpC/C+24VAyrk=; fh=5z4hNn4LCRbKTd1i4UBG0Xwg24Rjg1Dy3aTvDwPYAzg=; b=N8G1C+FnNvU+RqBMk79XATYcumsxQMDVramwjn20/rAatf4K0Q3N57FxL+OywQTjnp 43ESXwOA+EwgZ+xiA/o4jmJWhMn+sGwBV+FWgLjzWSevms7vz5B6VFrQlxQSs2ocleix In4zeTqeSzXkhNEMKRnegXsa0b4mQ6dicJBoYyAsj9w93SU5ermpqOgCtCNapyovxISy xvJoQg3tZTNQigjNCCzHjMEPuDeo8mPFxJLoS+asLPaLVsaLRjjAPNntn31PPvfGQPRw ApjD7O1s01tejSL9XFG07U9P6gOeAUPyvCsVLo70A/1oNW29nfoaAIkZ8bN+odzvjLrj N3Kg==; darn=zsh.org
- Arc-seal: i=1; a=rsa-sha256; t=1781126752; cv=none; d=google.com; s=arc-20240605; b=GB3SpbenrlgLhpElATQHgNtvwZVvos9J0MgTEBqaTtUfnrMEC1F2F4WHUG1dc84IiU HbcnKiJtApO1ybfrXqiT2IWlp9NRyz6IlUwXWoLJZb1SoaGbgqv3ITC7ytt6rRB1nejY Ilw4G05TGB1dGUrKbxMLRKBVlTL0Zjz/II6vyemot6YMjPD7Vgr7PRKmN4Y4b1rwfUsL YgzP6jqF2iBcTDwT9Cdf+4zCigeR+oLUXABzJQg4LTTyPVXnOLAHAo72q2tRC5pd4o3f lymYaNDQSu0cOK6POl0hmA/wxf3BhAMfa561aGmBEaSLyHsp/hBcoEfPY6ebi6TjPm9u V/Aw==
- Archived-at: <https://zsh.org/workers/54744>
- In-reply-to: <CAHYJk3QVQXtH_0hBZnVRnvzLJdPr7bmiM1S+8Rxxv2Ceix53jQ@mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
- References: <CAHYJk3RPgqh54Mky+5ar6_ui7H7mNzzuuxoYhTLRtxLrQE+1yQ@mail.gmail.com> <20260604071557.8072-1-mikachu@gmail.com> <CAH+w=7b-mukNw+RFBm3fnVT3Bh6+PftpUFEDxzLmf-2szXMfhw@mail.gmail.com> <CAHYJk3QVQXtH_0hBZnVRnvzLJdPr7bmiM1S+8Rxxv2Ceix53jQ@mail.gmail.com>
On Wed, Jun 10, 2026 at 9:17 AM Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
>
> If you, or anyone, have a specific change to suggest to the list of
> rules, that would be nice.
It depends on where in the sequence this occurs.
E.g. "internal flags" (typeset -u in your examples) are supposed to be
applied very early (rule #2). The only thing that happens before that
is nested substitution (described in rule #1 as ${...}) where it's
explicitly stated that "The flags are not propagated up to enclosing
substitutions". Also the -u flag explicitly says it's applied "when
the parameter is expanded". I believe rule #2 is meant to generalize
this to all of -l, -i, -E, etc.
So if "the value of the parameter is THEN substituted" and foo has the
-u flag, the expansion of ${foo::=bar} would be "BAR", not "bar". The
insertion of (U) into the expansion should make no difference, it
doesn't happen until step #12 (redundant with #2 in this example). On
the other hand, ${(L)foo::=bar} should override the -u flag and expand
to "bar". Even with your patch applied, this looks like it is what
happens:
(
typeset -u foo=bar
print ${foo::=${bar=lower}}
print ${(L)foo::=${bar=lower}}
typeset -p foo bar
)
LOWER
lower
typeset -u foo=lower
typeset bar=lower
This has more significance for the ${foo=bar} and ${foo:=bar} cases
where the order of operations would determine whether $foo is unset or
empty.
Next consider ${foo=${bar::=lower}. If the assignment to foo does not
happen, the assignment to bar doesn't happen either. This indicates
that the right-hand-side is NOT in fact a "nested expansion" per rule
#1, but instead is a whole new application of the "Rules" just before
the assignment occurs (in fact everything to the right is a simple
string replacement).
However, since ${(A)=ary::=$string} applies word splitting to $string
before performing the array assignment, expansion of $string must take
place before step #11, yet assignment doesn't happen until after that.
Odder still, ${(AzOu)=ary::=$string} expands in unique reverse-sorted
order but assigns in raw split order , in which case rule #2 should
have already been applied and ${foo::=bar} should be "bar", but it
isn't -- except in the examples where you throw in (P), which invokes
rule #4. Further, ${(AzOu)ary::=$string} assigns before splitting and
creates a single element array, even though it substitutes as a split
array. The assignment split is done by ${=ary} but the result split
is done by ${(z)ary}. So that would imply that assignment takes place
between steps #11 and #12. (I haven't dug into steps #13-#16.)
But that contradicts the first part about rule #2. The phrase "is
THEN substituted" is ambiguous in the description of the assignment
forms. Operationally, it looks like we start over again at rule #1
after deciding it's necessary to perform an assignment?
(
foo=bar
echo ${${foo}=fred}
echo ${${foo}:=fred}
{ echo ${${foo}::=fred} } always { TRY_BLOCK_ERROR=0; }
echo ${(P)${foo}::=fred}
echo $bar
)
bar
bar
zsh: not an identifier:
fred
fred
The result of the nested expansion is tested to determine unset/empty,
and then assignment is attempted.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author