Though my motivation in reporting this was to point out the segfault, I'm a
bit confused by why compound assignment should be an error here.
> Bash is consistent in defaulting to indexed array variables when you don't
> specify -A and assign a value using the compound assignment syntax.
Since localvar_inherit is new behavior anyway, I'm not sure why the above must
be the controlling default. I think a less surprising-to-the-user default
might be "when this option is set, Bash consistently inherits the
previous-scope variable's value/attributes before performing any new
value/attribute modifications".
In the alternative, it seems that Bash should be consistent in also
defaulting to indexed arrays in the case of `array[subscript]' assignments
with no -A specified?
i.e. if the following should be an error:
$ declare -A A; f() { local A=([Y]=Y); declare -p A; }; f
Segmentation fault: 11
should the following produce a local indexed array/an error as well (instead
of the associative array assignment it currently does)?
$ declare -A A; f() { local A[Y]=Y; declare -p A; }; f
declare -A A=([Y]="Y" )
> So you create a local indexed array variable, and when you attempt to
> inherit the value from a global associative array before performing any
> specified assignment, you should either ignore the inherited value or
> throw an error.
I feel like this doesn't seem very apparent from the documentation (though
it's not strictly contradictory, the step where we first check the RHS to see
if it is a compound array assignment seems surprising):
localvar_inherit
If set, local variables inherit the value and attributes of a variable
of the same name that exists at a previous scope *before any new value
is assigned*.
There's also an issue that only a value of a matching type is inherited and
the usual scalar-to-array[0] conversion is not performed. I'm not sure if
this is intentional but I do want to point it out as potentially surprising:
$ unset a s; a=(X) s=X
$ shopt -s localvar_inherit
$ f() { local -a a s; declare -p a s; }; f
declare -a a=([0]="X")
declare -a s=()
$ f() { local a+=(Y) s+=(Y); declare -p a s; }; f
declare -a a=([0]="X" [1]="Y")
declare -a s=([0]="Y")
$ f() { local -a a+=Y s+=Y; declare -p a s; }; f
declare -a a=([0]="XY")
declare -a s=([0]="Y")
Maybe I'm missing the intended use of the option but based on the description
in the man page, I guess I'm expecting `declare var' with localvar_inherit to
be roughly the same as `eval $(declare -p var 2>/dev/null); declare var'
without it (except for namerefs). Is there maybe a use case for the
differences in behavior?
As a side note: I wonder if this functionality, regardless or edge case
handling, would be more useful as an option supplied to `declare' and so
applied explicitly so specific variables, rather than a global shell option.