2014-12-14 14:57:15 -0500, Chet Ramey: [...] > Well, I don't think it's particularly a syntax issue. It's the question > I wrote in my previous message: how much further should we move compound > assignment away from the execution semantics associated with builtins. [...]
IMO, the ksh behaviour is the closest one can get to a consistent approach and still allow assignments to arrays: act like an assignment modifier except when the arguments don't form valid assignment (simple command parsing then, and only scalar assignments for arguments that contain "="). declare var=(1 2 3) declares and sets an array only as long as "var=(" and ")" are litteral (as in not the result of any expansion) and unquoted and "var" is a valid identifier. declare "var="(1 2 3) or declare ""var=(1 2 3) would be syntax errors. declare var=$foo doesn't perform word splitting but assigns the content of $foo as a string to $var (or ${var[0]} if an array, or ${var["0"]} if a hash). declare "var="$foo declare ""var=$foo declare $foo=$foo would perform split+glob on $foo. (parsed like a normal command) declare var="("[123]=bar")" parsed like a scalar assignment (no globbing on that unquoted [123], no hash/array assignment. In short, all the assignments you can do without declare should work the same with declare. And things that would not be treated as an assignment without declare (like \a=foo, ${1+a=$1}...) are parsed normally as arguments to declare, and declare by itself only does scalar assignments including to array members, never array or hash assignment. ksh supports: $ ksh -c 'typeset a[1]=(1 2 3); typeset -p a' typeset -a a=([1]=(1 2 3) ) but that's because it supports nested arrays. It makes sense for bash to just return an error there (as it does already). declare would still end up do some indirect evaluation as part of arithmetic evaluation in array subscript: foo='a[0$(uname>&2)]=foo' declare "$foo" would still run uname before assigning foo to a[0]. I'd rather it doesn't do that (only expand $(...) when litteral), but if we fix it here, we'd need to fix it everywhere else as well. Does that make sense? BTW: $ bash -c 'declare a[1]="(1 2 3)"; declare -p a' declare -a a='([0]="1" [1]="2" [2]="3")' $ bash -c 'declare a+=([1]="1 2 3"); declare -p a' bash: line 0: declare: `a+': not a valid identifier declare -a a='([1]="1 2 3")' How do I do ATM if I want a[1] to contain "(1 2 3)" with declare? -- Stephane