|
From: | Grisha Levit |
Subject: | Re: declare [-+]n behavior on existing (chained) namerefs |
Date: | Wed, 27 Apr 2016 20:03:50 -0400 |
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.
>
[Prev in Thread] | Current Thread | [Next in Thread] |