Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: RC_EXPAND_PARAM bug
- X-seq: zsh-workers 3390
- From: Zoltan Hidvegi <hzoli@xxxxxxxxxxxxxxx>
- To: schaefer@xxxxxxxxxxxxxxxx (Bart Schaefer)
- Subject: Re: RC_EXPAND_PARAM bug
- Date: Wed, 30 Jul 1997 01:16:10 -0400 (EDT)
- Cc: zsh-workers@xxxxxxxxxxxxxxx (Zsh hacking and development)
- In-reply-to: <970729092705.ZM16897@xxxxxxxxxxxxxxxxxxxxxxx> from Bart Schaefer at "Jul 29, 97 09:27:05 am"
> } > % echo ${^a}$[i++]$[++j]${^x}....
> } >
> } > where .... is some arbitary number of other substitutions? Is it just that
> } > it now does everything from right to left instead of left to right? Why?
> }
> } No, it is left to right. ${^a} is expanded first, then the remaining
> } part, $[i++]$[++j]${^x} is expanded separately, and the result is
> } combined with the expansion of ${^a}. You can see it if you try
> }
> } let i=0; echo $[i++]${^a}$[i++]
> }
> } which gives
> }
> } 0a1 0b1
>
> I'm still not comprehending this.
>
> Are you saying that all the variables are expanded first, left to right,
> and then all the resulting strings are combined? Whereas before (2.6 and
> earlier) each variable would be expanded and combined with what followed,
> and then the process repeated for each new string?
OK, I tell you what subst.c does. You have a string of the form
prefix${^a}suffix
Suppose that prefix does not have anything to expand. paramsubst is
called to expand this string, which expands ${^a}. There are three
cases:
1. `a' was an empty array. In that case the expansion is the empty list,
and suffix is not evaluated (so even if there is a $[i++] in suffix, i
will not change).
2. `a' had one element: paransubst replaces ${^a} with its value and
returns and the calling routine, stringsubst, which continues parsing
the suffix. If that suffix contains some other parameter expansions,
paramsubst will be called again.
3. `a' has more than one elements. In that case stringsubst is called
for suffix alone (which may call paramsubst again to expand something
in suffix), and the result will be be a list. This list is combined
with the expansion of ${^a}. If suffix expands to an empty list, the
result will be empty, otherwise the result is the first element of `a'
combined with the each element from the expansion of suffix, followed
by the second element of `a' combined with list etc. Note that suffix
can only expand to an empty list as a result of an rc-expansion in
suffix (that's because null-argument removal is only done in prefork
after stringsubst). With this, in ${^a}1${^^x} the expansion of
1${^^x} gives two elements, 1x y, which is combined with `a'. If you
replace 1${^^x} with 1${^x}, it is expanded to 1x 1y instead of 1x y.
This guarantees left to right evaluation, everything is evaluated at most
once, and everything is evaluated once unless there is an rc-expansion of
an empty array which discards everything following that array.
The 2.6-beta16 and earlier behavior:
${^a} was expanded, and a list was created prepending prefix and
appending suffix for each array element. The resulting list is parsed
again from the beginning. For example:
a=('${~^a}' '${~^a}')
prefix${~^a}suffix
expands to
prefix${~^a}suffix prefix${~^a}suffix
and the expansion is restarted, the first element of this list is
expanded again, the result is
prefix${~^a}suffix prefix${~^a}suffix prefix${~^a}suffix
and the expansion is restarted... For this infinite loop, the ~ or the
globsubst option was necessary.
What would be the preferred evaluation of ${^a}1${^^x}?
Alternatives:
1. a1x ay b1x by (current)
2. a1x y b1x y (beta16 and older)
3. a1x b1x y (just an other logical solution).
The current behaviour is the simplest to code solution, I think the other
two are not very hard to implement, but I'm not sure it is worth the
extra effort.
Zoltan
Messages sorted by:
Reverse Date,
Date,
Thread,
Author