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

Empty element elision and associative arrays (was Re: Slurping a file)



On Sun, Jan 14, 2024 at 4:03 PM Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
>
>> Elision of empty values is a property of unquoted expansion.  It
>> has NOTHING to do with variable types.
>
> I'll take another look, thanks.  I may have gotten my wires crossed.

When assigning to an associative array ...

% typeset -A asc=( $something )

... the expansion of $something has to yield an even number of
"words", yes.  But remember the previous lesson about those outer
parens -- they only mean that the thing to the left is an array, they
don't matter to what's inside those parens.  So if $something is an
array with empty elements, those elements are going to be elided,
which might leave you with an odd number of words and break the
assignment -- or possibly worse, turn some values into keys and some
keys into values.

Another thing that may be confusing you is that associative arrays
only expand their values by default, and an empty value will be elided
just like any other empty array element.

% typeset -A asc=( one 1 two 2 three 3 nil '' )
% typeset -p asc
typeset -A asc=( [nil]='' [one]=1 [three]=3 [two]=2 )
% printf "<<%s>>\n" ${asc}
<<1>>
<<2>>
<<3>>
% printf "<<%s>>\n" "${asc[@]}"
<<1>>
<<2>>
<<3>>
<<>>

(output may vary because associative arrays are not ordered).

Also, an empty key can have a value:

% asc+=( '' empty )
% typeset -p asc
typeset -A asc=( ['']=empty [nil]='' [one]=1 [three]=3 [two]=2 )
% printf "<<%s>>\n" ${asc}
<<empty>>
<<1>>
<<2>>
<<3>>

But if you reference the keys, the empty one will be elided when not quoted:

% printf "<<%s>>\n" ${(k)asc}
<<one>>
<<two>>
<<three>>
<<nil>>
% printf "<<%s>>\n" "${(@k)asc}"
<<>>
<<one>>
<<two>>
<<three>>
<<nil>>

Returning to the original example, that means if  you're copying one
associative array to another, you need to copy both the keys and the
values, and quote it:

% typeset -A asc=( "${(@kv)otherasc}" )




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