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

Re: PATCH: Add :^ syntax for zipping two arrays



On 1 August 2014 10:46, Peter Stephenson <p.stephenson@xxxxxxxxxxx> wrote:
> On Thu, 31 Jul 2014 19:45:39 +0200
> Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
>> Any objections to adding this? Comments on the code is also welcome
>> since I'm not at all sure I thought of all the gotchas in paramsubst(),
>> in particular some allocations might be leaking? Not adding tests until
>> any and all comments are incorporated.
>
> That looks pretty reasonable, but I think all the allocations need to be
> on the heap at this point (though it's certainly potentially confusing):
> so zalloc needs to be zhalloc, ztrdup needs to be dupstring, and mkarray
> needs to be... er... however you do mkarray on the heap; I think you
> just zhalloc(2), copy the first element, and set the second to
> NULL, though I don't see why you couldn't add an hmkarray().
>
> Generally, the command line expansion stuff is all done on the heap ---
> it doesn't get turned into permanent allocation until assigned to a
> variable, added to a hash, stored as a function definition, or whatever.

Yeah, when I started writing the code I had forgotten that arrays are
literally just arrays, and not a special zsh array type, so I was
looking for more array handling functions, then remembered. Anyway, I
modeled it loosely on the :| / :* code which is just below it, which
uses mkarray, zhalloc and dupstring, which is... confusing. (I was
probably looking at another piece of code while writing ztrdup and
zalloc, changed those now).

> Then it looks like it ought basically to work.  Some tests would be
> useful.

Got some comments on IRC that in other languages, zip() functions
usually stop at the end of the shorter array, so I made that the
behavior for :^ and added :^^ for the behavior in the patch I sent.

I noticed a problem though, and that is inside double quotes. a=(1 2);
"${a:^a}" produces two separate array elements as output when you
might expect a single space joined thing from anything inside double
quotes (and the elements it outputs are "1 2" and "1"). I'm not
entirely sure how to handle that. For the :| and :* operator, you only
ever remove elements, so once the original array is joined together,
you don't accidentally add more. I tried looking at isarr but it's 0
both inside double quotes and when the input is actually a scalar
outside double quotes. Is there some other parameter I could examine?
I don't think there's really any sensible output you can get out of
"${a:^b}" without also adding (@) but I should at least detect it so
as to not output multiple elements... although I suppose someone might
want the output of "${a:^^b}" (which is the whole array $a joined
together by spaces, shown fully between each element of b, and then
joined together by spaces again? I don't think I want to support that.
Actually the effect seems achieved already by nesting again inside
${})

-- 
Mikael Magnusson



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