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.comhttp://masterpasswordapp.com

Reply via email to