[Top][All Lists]

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

Re: ${y@a} on an empty array y fails with 'y: unbound variable' if run w

From: Mark March
Subject: Re: ${y@a} on an empty array y fails with 'y: unbound variable' if run with set -u
Date: Tue, 26 Oct 2021 17:07:24 +0000 (UTC)

>"An array variable is considered set if a subscript has been assigned  a 

My bad, I missed that. However, there is an argument to be made that ${foo@a} 
and ${foo@A} transforms should be exempt from the nounset option if foo is an 
unset array. An attempt to obtain the value (or something derived from the 
value, such as its length) of an unset variable is clearly a bug in one's code. 
But ${foo@a} and ${foo@A} expand to the _attributes_ of the variable, not its 
value. It's fine to consider an array unset if it has no indexes/key, but even 
though it is unset such an array still has attributes. Bailing out on an 
attempt to access attributes (which clearly exist and can be obtained with 
declare -p at the cost of forking a subshell) just because the variable has no 
value seems counterintuitive and counter to the intended purpose of the nounset 
option, which is to help the programmer catch bugs in her code. 

>That was the result of a long discussion:

It seems that in that thread you agreed to take steps towards making ${foo@a} 
succeed when declare -p foo would succeed. I would argue that this should also 
work under nounset, but I see how this may be a tough call since ${foo@a} is 
technically a parameter expansion, although of a new kind -- to a string 
derived from something other than the value of the parameter. I will just put 
[[ -o unset ]] && { set +u; ... set -u; } around my [[ ${foo@a} =~ A ]] for now.

Thanks again for your explanation and context.

On Tuesday, October 26, 2021, 07:02:59 AM PDT, Chet Ramey <chet.ramey@case.edu> 

On 10/25/21 8:24 PM, Mark March wrote:
> If -u is on and you declare a simple or associative array 'y' and set it 
> empty, then ${y@a} will fail with 'unbound variable'.

It really is unset:

"An array variable is considered set if a subscript has been assigned  a

> I was able to repro this under 5.1.0(1)-release and 5.1.8. 5.0.17(1)-release 
> does not seem to be affected.

Bash-5.1 fixed some bugs in this area.

> The code to reproduce (output lines begin with #>):
> #> 5.1.0(1)-release
> set -u
> declare -a y=()
> echo ${y@a}
> #> bash: y: unbound variable

Yes, because it's unset, but see below.

> declare -p y
> #> declare -a y=()
> echo ${y[@]}
> #>

The `@' and `*' subscripts are exempted from the nounset option to parallel
the behavior of `$@' and `$*' when there are no positional parameters (the
latter is specified by POSIX).

> set +u
> echo ${y@a}
> #> a
> As you can see, turning off -u makes ${y@a} work correctly. 

If the `nonunset' option is not enabled, there is a special case for the
`a' transform so it will print the attributes of an unset array variable.

That was the result of a long discussion:


> I wonder if this is a side-effect of the fix that you described in item (n) 
> of the most recent change log:
> n. Fixed a bug that caused ${foo@a} to treat foo as an unset variable if it 
> was an array without a value for subscript 0/"0" but had other set elements

This is not relevant, there are no set elements.

``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]