[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Inconsistent behaviour of +=() and existing array keys

From: Maarten Billemont
Subject: Inconsistent behaviour of +=() and existing array keys
Date: Fri, 28 Nov 2014 15:47:49 -0500

So, referring to man bash, this is the description of +=:

When += is applied to an array variable using compound assignment (see Arrays below), the variable's value is not unset (as it is when using =), and new values are appended to the array beginning at  one greater  than  the  array's  maximum  index  (for indexed arrays) or added as additional key-value pairs in an associative array.

This description does not help us understand what should happen when this syntax explicitly mentions keys and more specifically, ones that already exist within the array.

Intuition would likely have us believe that since +=() mutates the array by adding the elements to it, consistency would imply that when you specify elements by key, the array would either gain an element for that key or change the existing element at that key.

So if we were to run this code:

declare -a indexed_array=( [0]=a )
declare -A associative_array=( ["x"]=a )
indexed_array+=( [0]=b [1]=c )
associative_array+=( ["x"]=b ["y"]=c )
declare -p indexed_array associative_array

Here's what I would expect to see:
declare -a indexed_array='([0]="b" [1]="c")'
declare -A associative_array='([x]="a" [y]="c" )'

Instead, we get this:
declare -a indexed_array='([0]="ab" [1]="c")'
declare -A associative_array='([x]="ab" [y]="c" )'

So the current behaviour appears to change the meaning of +=() as either mutating the array or mutating the array elements, depending on whether the specified key already exists within the array.  I believe this behaviour to not only be counter-intuitive but also dangerous: the same syntax now has two distinct meanings depending solely on what data already exists within the array.

Even more interestingly, it is apparently also legal to use the += operator within the element assignment syntax:

indexed_array+=( [0]+=b [1]+=c )

This appears to behave exactly as a normal = would there.

What I would expect is for += inside +=() to behave as = does now, and = to behave as it does outside of +=(), which is to "set" the value, not append.  Ergo:

declare -a indexed_array=( [0]=a )
indexed_array=( [0]=b ) #=> [0]=b  -- because we unset the array and set the element so those given.
indexed_array+=( [0]=b ) #=> [0]=b -- because we mutate the array by setting the element to that given.
indexed_array=( [0]+=b ) #=> [0]=b -- because we unset the array and set the element by appending the given to nothing.
indexed_array+=( [0]+=b ) #=> [0]=bb -- because we mutate the array by appending the given to what is already there.

Maarten Billemont (lhunath)
me: http://www.lhunath.com – business: http://www.lyndir.com – http://masterpasswordapp.com

reply via email to

[Prev in Thread] Current Thread [Next in Thread]