bug-bash
[Top][All Lists]
Advanced

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

Re: self-reference to assoc.-array variable


From: Chet Ramey
Subject: Re: self-reference to assoc.-array variable
Date: Tue, 20 Sep 2022 10:26:39 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.2.2

On 9/15/22 4:46 PM, kurt wrote:

Bash Version: 5.1
Patch Level: 16
Release Status: release

Description:
         a declaration like the following was possible before bash-version 5.1:
                 declare -r -A MYAR=(
                   ['first']="NUMBER ONE"
                   # --- 'self-reference' to declaring array variable MYAR
                   ['top']="${MYAR['first']}"
                 )
                 echo "${MYAR[@]}"
         now bash complains with a syntax-error on the 
['top']="${MYAR['first']}" construct

Here's the reply I sent to kurt via private email, since he sent me the
same report with a slightly different example:

> In several scripts I use assoc. arrays for kind of aliases.
> To prevent value-duplication I referenced the first declaration of an element.
> Here's an example on how it worked before bash 5.1:
>
> #!/bin/bash
> set -euo pipefail
> _main() {
>    local IFS=$'\n'
>    local -r -A MYAR=(
>      ['first']="NUMBER ONE"
>      ['top']="${MYAR['first']}"
>    )
>    echo "${MYAR[@]}"
> }
> _main "$@"
>
>
> Now I get
>
> Zeile 7: 'first': Syntaxfehler: Operator erwartet (fehlerverursachendes Zeichen ist "'first'")

The idea is that `local' is a builtin, and builtins (like other commands)
perform word expansion on their arguments before the builtin is invoked,
so the order of evaluation is different than what you expect. In this case,
the words in the compound assignment are expanded before the array is
created by the `local' builtin. Since you have `nounset' enabled, you get
a fatal error.

Even the rhs of a compound assignment statement is treated this way: the
assignments are expanded, the associative array is created, and finally
it's assigned to the variable.

I made this change to avoid inconsistencies like the one reported in

https://lists.gnu.org/archive/html/bug-bash/2019-07/msg00112.html

Before that change making the order of evaluation explicit, the array
assignment would first flush the array contents (which is what happens
on a compound array assignment without using `+='), then expand the
words in the assignment.

You can get the results you want in a way that's compatible with both
versions by splitting the assignment into two statements, then setting
the readonly attribute:

  local -A MYAR=( ['first']="NUMBER ONE" )
  MYAR['top']="${MYAR['first']}"
  local -r MYAR




--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://tiswww.cwru.edu/~chet/




reply via email to

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