this one does not seem like a bug to me, rather a decision made by the author: to interpret "on the variable" from this:
"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." as doing a depth first search (going as deep as possible over the reference chain) in order to find the variable. The last case you mention is discussable: when the leaf is an empty reference should +n do something? Probably should do the same as declare +n ref_N; which I think is just to leave a variable with identifier ref_N. But then, ref_((N-1)) points to a variable and suddenly there is a potentially unexpected change in your lovely tree of empty references. One can argue: if you pass the ref_i to some function, and you want to modify ref_N how to do it? The choice made seems fairy logical, I am not saying that it is the best possible one though. cheers, pg On 27 Apr 2016, at 21:26, Grisha Levit wrote: > 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" # unchanged > declare -n ref2="ref3" > declare -n ref3="var2" # changed > # declare +n ref1 > # declare -p ref{1..3} > declare -n ref1="ref2" # unchanged > declare -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" # unchanged > declare -n ref2="ref3" # unchanged > declare -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. >