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

Re: is this a problem?

On Sat, 2 Aug 2014 09:12:37 +0800
Han Pingtian <hanpt@xxxxxxxxxxxxxxxxxx> wrote:
> Looks like a problem:
> 	% zsh -f
> 	localhost% array=(two three)
> 	localhost% setopt rcexpandparam
> 	localhost% print -l ${:-one $array}
> 	one two
> 	one three
> 	localhost% print -l ${=:-one $array}
> 	one
> 	two
> 	three
> 	localhost%
> I think the last command should have printed
> 	one
> 	two
> 	one
> 	three
> but it isn't.

The output is correct; splitting into words with `=' occurs before
application of RC_EXPAND_PARAM or the '^' flag.  The only problem is
that it's not actually documented at which point the combination
according to RC_EXPAND_PARAM occurs, which is rather late in the day.
Splitting occurs way back at rule 11, which is why you have the array
(one two three) by this point.

Actually, it's correct less by design than by 'that's the way it's
always been'.  The rules modified below are more a list of the
horrifically complicated things that happen in parameter expansion than
a definition of how they're supposed to work.  For the same reason, if
you find that something happens in a particular order, unless you happen
to know for a fact it's supposed to happen in a different order, it's
not usually sensible to report it as a bug, except in the documentation.
We'd be *very* loathe to change the ordering now unless it's glaringly

Nesting the expansion is the usual way to get things to happen in the
way you want rather than the order defined by the code.

% print -l ${=${:-one $array}}

Note for me and Bart and anyone else who is interested (if we haven't heard
from you yet please get in touch :-)): the ordering of the (new) rules 20 and
21 is a little bit underdefined since we do the re-evaluation in the course
of the RC_EXPAND_PARAM expansion.  But I think in practice it works OK.

diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index ff9f2b1..7279013 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -1407,16 +1407,21 @@ item(tt(19.) em(Ordering))(
 If the result is still an array and one of the `tt((o))' or `tt((O))' flags
 was present, the array is reordered.
-item(tt(20.) em(Re-evaluation))(
+item(tt(20.) tt(RC_EXPAND_PARAM))(
+At this point the decision is made whether any resulting array elements
+are to be combined element by element with surrounding text, as given
+by either the tt(RC_EXPAND_PARAM) option or the `tt(^)' flag.
+item(tt(21.) em(Re-evaluation))(
 Any `tt((e))' flag is applied to the value, forcing it to be re-examined
 for new parameter substitutions, but also for command and arithmetic
-item(tt(21.) em(Padding))(
+item(tt(22.) em(Padding))(
 Any padding of the value by the `tt(LPAR()l.)var(fill)tt(.RPAR())' or
 `tt(LPAR()r.)var(fill)tt(.RPAR())' flags is applied.
-item(tt(22.) em(Semantic joining))(
+item(tt(23.) em(Semantic joining))(
 In contexts where expansion semantics requires a single word to
 result, all words are rejoined with the first character of tt(IFS)
 between.  So in `tt(${LPAR()P)tt(RPAR()${LPAR()f)tt(RPAR()lines}})'
@@ -1425,7 +1430,7 @@ joined again before the tt(P) flag can be applied.
 If a single word is not required, this rule is skipped.
-item(tt(23.) em(Empty argument removal))(
+item(tt(24.) em(Empty argument removal))(
 If the substitution does not appear in double quotes, any resulting
 zero-length argument, whether from a scalar or an element of an array,
 is elided from the list of arguments inserted into the command line.

Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/

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