bug-bash
[Top][All Lists]
Advanced

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

issues with nameref resolution loop in a function


From: Grisha Levit
Subject: issues with nameref resolution loop in a function
Date: Sat, 8 Dec 2018 20:30:42 -0500

There seems to be an issue with the following new bash-5.0 feature:

  A nameref name resolution loop in a function now resolves to a variable by
  that name in the global scope.

[ Note: "warning: x: circular name reference" messages omitted below. ]

While referencing such a nameref works as described, scalar assignment to it
modifies the variable from the next higher scope rather than the global one:

    $ inner() { local -n x=x; x=3; }
    $ outer() { local x=2; inner; declare -p x; }
    $ x=1; outer; declare -p x
    declare -- x="3"            # x changed in outer()
    declare -- x="1"            # global x not changed

There is odd/broken behavior when `declare' is used to modify such a
variable,
similar to https://lists.gnu.org/archive/html/bug-bash/2018-07/msg00072.html
I think the right thing here would be for `declare' to act as if the `-g`
flag
had been supplied and modify the variable in the global scope?

    $ f() { local -n x=x; declare x=(2); x=3; declare -p x; }
    $ x=1; f; declare -p x
    declare -an x=([0]="2")     # local nameref borked
    declare -- x="1"            # global x not changed

    $ f() { local -n x=x; declare x=2; }; f
    -bash: declare: `2': invalid variable name for name reference

    $ f() { local -n x=x; declare -a x=y; declare -p x; }
    $ x=1; f; declare -p x
    declare -an x=()            # local nameref borked
    declare -a x=([0]="y")      # global x correct (?)
    $ unset x; declare -p x
    declare -- x="1"            # original after unset

`unset' (no `-n') modifies the nameref:

    $ f() { local -n x=x; unset x; declare -p x; }
    $ x=1; f; declare -p x
    declare -- x
    declare -- x="1"

If the target is an array reference that results in a circular nameref,
then
neither referencing nor assigning to the nameref works:

    $ f() { local -n x=x[0]; echo "<$x>"; x=2; }
    $ x=1; f
    <>
    -bash: `x[0]': not a valid identifier


reply via email to

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