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

Re: Array expansion interacts with brace expansion in the wrong order

On Fri, Jul 14, 2017 at 2:41 AM, Peter Stephenson
<p.stephenson@xxxxxxxxxxx> wrote:
> The problem is that
> a=(1 2 3)
> print {$^a,4,5,6}
> doesn't expand $^a at the same time as the braces, because all array
> expansion comes before all brace expansion.  So how do you get 1 2 3 4 5
> 6 treated as a set of array elements without actually constructing an
> array?

That's not precisely the question, is it?  If it were, the answer
would simply be to write
    $a 4 5 6

The question is how to get that to behave like a brace expansion with
respect to the surrounding text.

> If you're not too fussy about embedded spaces, you can do
> % print x${^=:-$a 4 5 6}y
> x1y x2y x3y x4y x5y x6y
> I haven't come up with a way that allows you effectively to extend the
> array without using the hack of splitting up strings.

The root of the problem is that both $^a and {4,5,6} do lexical
catenation with the surrounding text (which, in the absence of word
splitting, is consistent with how the shell language always catenates
adjacent tokens), but the problem requires what might be called
semantic catenation (appending two arrays results in one longer array
without altering individual elements).

This handles embedded spaces in $a better:

print -l x${^:-$a${=:- 4 5 6}}y

(note, the space between =:- and 4 is important, you need an extra
empty element to catenate with $a)

Another way to deal with embedded spaces in elements of $a:

% print x${(z)^:-${(q)a} 4 5 6}y

The "squiggles" there mean

- (z) splits the expansion as if parsing a command line
- ^ ensures that array expansion behaves like brace expansion.
- :- says "use the following if there's no parameter string yet".
- (q) quotes the elements [later unquoted by (z)]

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