Re: Changing the way bash expands associative array subscripts
On 4/6/21 12:46 PM, Koichi Murase wrote: How about the cases with `test -v a[@]' and `key=@; test -v a[$key]'? By the time test sees its arguments, there is no difference between these two cases. You can do things to differentiate when running the `[[' command, but `test' goes through the entire set of word expansions. I remember there was some discussion in the bug-bash list on the behavior of `test -v a[@]' which actually tests whether the array `a' has at least one element. It cannot be replaced by `test -v a' because `a' implies `a[0]' here. But if I correctly understand it, `test -v a[@]' can be replaced by `((${#a[@]}))'. Should any scripts relying on `test -v a[@]' to test the array elements also be changed? I'm ok with making the old behavior contingent on a compatibility setting, like with `unset'. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: Changing the way bash expands associative array subscripts
On 4/6/21 12:46 PM, Koichi Murase wrote: Looking at another thread https://lists.gnu.org/archive/html/bug-bash/2021-04/threads.html#00051, I'm now also interested in how we can handle the indirect expansions for 'a[@]' and the namerefs for 'a[@]': $ declare -A a=(['@']=x [1]=y) $ $ # indirect expansions $ iref1=a[@]; printf '<%s>' "${!iref1}"; echo $ key=@; iref2=a[$key]; printf '<%s>' "${!iref2}"; echo # <-- unexpected But these cases are identical. After the assignment statement, iref2 has value 'a[@]', just like iref1. I don't see why one would be more unexpected than the other, and they're both equivalent to ${a[@]}. Unless that's your point? $ # namrefs $ declare -n nref1=a[@]; printf '<%s>' "$nref1"; echo $ key=@; declare -n nref2=a[$key]; printf '<%s>' "$nref2"; echo # <-- unexpected Yes, namerefs are different, but not in a way that matters here. These two cases are identical as well. If you added `declare -p nref2', you'd see it. (The differing output issue got fixed back in January, the result of https://lists.gnu.org/archive/html/bug-bash/2021-01/msg00148.html) I guess I see what your point might be, but these aren't different cases. Variables don't carry around the kind of state that might be used to differentiate their behavior depending on the value they got at assignment time. There is no useful syntactic information there. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: Changing the way bash expands associative array subscripts
On 4/9/21 12:20 PM, Koichi Murase wrote: That said, the fact that you can put 'a[@]' in an indirect variable and get an array expansion out of "${!x}" is completely repulsive to me. Currently, we need to write as «iref='a[$key]'; echo "${!iref}"» so that $key is not expanded until the referencing (just like «unset 'a[$key]'»). If the new assoc_expand_once enables the indirect expansions of the form «iref="d[$key]"; echo "${!iref}"» like «unset "a[$key]"» and also if we don't change the current behavior of «iref=a[@]; echo "${!iref}"» (being expanded to all the elements of the array) as Greg's suggestion, we need to work around the case key=@ for «iref="d[$key]"; echo "${!iref}"». However, it seems to me that there is no workaround. What string should we assign to `iref' to create a reference to the element associated with key=@ with Greg's suggestion? Ah, ok. I see. You can assign '\@' to iref to get the behavior you want. It's not perfect, but it's possible: $ cat x6b shopt -s assoc_expand_once declare -A a=(['@']=x [1]=y) printf '<%s>' "${a[@]}"; echo printf '<%s>' "${a[\@]}"; echo iref1='a[\@]' echo "$iref1" printf '<%s>' "${!iref1}"; echo key='\@'; iref2=a[$key] echo "$iref2" printf '<%s>' "${!iref2}" ; echo $ ./bash ./x6b a[\@] a[\@] Once you choose to have ${a[@]} expand to all the elements of an array, whether it's indexed or associative -- and that choice came years ago -- using that character as a key is always going to require a workaround. Some of them won't be pretty. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/