[Top][All Lists]

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

Re: Changing the way bash expands associative array subscripts

From: Koichi Murase
Subject: Re: Changing the way bash expands associative array subscripts
Date: Tue, 13 Apr 2021 18:01:11 +0900

2021年4月13日(火) 0:16 Chet Ramey <chet.ramey@case.edu>:
> 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
> > <y><x>
> > $ key=@; iref2=a[$key]; printf '<%s>' "${!iref2}"; echo
> > <y><x>    # <-- 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?

That's my point. Sorry for my insufficient explanation. I know why
these examples don't work in the *current* Bash. I also think it
wouldn't work with a naive design of *new* assoc_expand_once either.
But I expected some design consideration enabling a[$key] for an
arbitrary key in the indirect expansions and namerefs. (By *new*
assoc_expand_once in the previous and this reply, I meant the planned
change on assoc_expand_once but not the current behavior of

> > 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:

Sorry, I'm a bit confused. May I confirm that we are talking about the
behavior after the planned change on the subscript expansions? If you
are talking about the solution with the current Bash, I know that. If
you are talking about the new behavior as I expect, why would
«iref='a[\@]'» work?

(a) Is it because indirect expansions and name references are not
planned to be modified this time (unlike `unset') and will still
require careful quoting of the key strings after the change?

(b) Or, is it because the associative array subscripts will still be
subject to quote removal after the change even though the command
substitutions in the subscripts will not be evaluated (as shown in
your initial example «unset -v a["$key"]» in
https://lists.gnu.org/archive/html/bug-bash/2021-03/msg00056.html )?

I thought the purpose of the planned change of the associative array
subscripts is to solve the inconsistency between the usages of ((
a[\$key] )), unset 'a[$key]', etc. and the usages of a[$key]=xxx,
${a[$key]} so that we can write (( a[$key] )), unset "a[$key]",
iref=a[$key], declare -n nref=a[$key], etc.  With both cases of the
above (a) and (b), we still cannot write «iref=a[$key]» and «declare
-n nref=a[$key]» for arbitrary keys but need to write
«iref=a[$quoted_key]» with a non-trivial conversion of the key to
`quoted_key'.  If so, I feel that the change of this time wouldn't
reduce the inconsistency but just changes the boundary where the
inconsistency happens?


reply via email to

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