bug-bash
[Top][All Lists]
Advanced

[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: Alex fxmbsw7 Ratchev
Subject: Re: ${y@a} on an empty array y fails with 'y: unbound variable' if run with set -u
Date: Tue, 26 Oct 2021 19:15:03 +0200

if u're trying to save a var, or rename one, declare -p output saving was
my way to do so

On Tue, Oct 26, 2021, 19:09 Mark March <march@systempad.org> wrote:

> >"An array variable is considered set if a subscript has been assigned  a
> value."
>
> 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:
> >
> >https://lists.gnu.org/archive/html/bug-bash/2020-02/msg00050.html
>
> 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.
> -Mark
>
>
>
> On Tuesday, October 26, 2021, 07:02:59 AM PDT, Chet Ramey <
> chet.ramey@case.edu> wrote:
>
>
>
>
>
> 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
> value."
>
> > 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 #>):
> >
> > echo $BASH_VERSION
> > #> 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:
>
> https://lists.gnu.org/archive/html/bug-bash/2020-02/msg00050.html
>
>
>
> > 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.
>
> Chet
> --
> ``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]