declare -n name=value, when name is already a nameref, shows the following
presumably inconsistent behavior:

Given a chain of namerefs like:

ref_1 -> ref_2 -> ... -> ref_i ... -> ref_N [-> var]

   - If ref_N points to a name that is not a nameref, the operations declare
   -n ref_N=value and declare +n ref_N modify the value/attributes of ref_N
   (this seems to be the desired behavior)
   - For i<N, declare -n ref_i=value and declare +n ref_i modify the
   value/attributes of ref_N and not of ref_i
   - If ref_N is declared as a nameref but unset, then these operations on
   ref_i have no effect.

For example, starting with:

unset -n ref{1..3}declare -n ref1=ref2 ref2=ref3 ref3=var1

# declare -n *ref1*=*var2*# declare -p ref{1..4}declare -n ref1="ref2"
  # unchangeddeclare -n ref2="ref3"declare -n *ref3*="*var2*"   #
changed

# declare +n *ref1*# declare -p ref{1..3}declare -n ref1="ref2"   #
unchangeddeclare -n ref2="ref3"declare -- *ref3*="var1"   # changed,
no loner nameref

Or alternatively:

unset -n ref{1..3}declare -n ref1=ref2 ref2=ref3 ref3

# declare +n ref1# declare -p ref{1..3}declare -n ref1="ref2"   #
unchangeddeclare -n ref2="ref3"   # unchangeddeclare -n ref3
# unchanged

# declare -n ref1=var1# declare -p ref{1..3}declare -n
ref1="ref2"declare -n ref2="ref3"declare -n ref3

The man page says:

All references, assignments, and attribute modifications to name, except
for changing the -n attribute itself, are performed on the variable
referenced by name’s value.

This does not appear to be the case, as declare -n ref_N=value changes
$ref_N, not $value, and declare +n ref_i changes ref_N.
​

Reply via email to