> interpret "on the variable" as doing a depth first search (going as deep as possible over the reference chain) in order to find the variable
Yes, that makes perfect sense, but I think all the issues above don't concern the search for the variable, but rather modifications to the references themselves. This might just be a documentation issue, as the docs state that something different should be happening: 1. It seems unambiguous from the description that `declare +n ref_1' should remove the nameref attribute from ref_1, not from any other variable 2. A strict interpretation would also suggest that `declare -n ref_1=foo' should change the value of the variable referenced by the nameref (or the chain of references), not the value of ref_N. I don't know if that's really the implementation's intention -- perhaps adding a note to the "If a variable name is followed by =value, the value of the variable ..." section of the declare builtin's description would help clarify this case. On Wed, Apr 27, 2016 at 5:54 PM, Piotr Grzybowski <narsil...@gmail.com> wrote: > > 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. > > > >