Re: Is this the expected behaviour for nameref in Bash 4.4 now?
thank you for the insight, it's very helpful! On Oct 28, 2016 10:01 AM, "Chet Ramey" wrote: On 10/20/16 2:45 PM, kjk...@gmail.com wrote: > set -x > > var_123=123 > f() { > while (( $# )); do > shift > local var=var_123 > local -n var=$var; : status is $? > local -p > : var is $var > done > } > > f one two > > > Running above script gives the follow output: > > + var_123=123 > + f one two > + (( 2 )) > + shift > + local var=var_123 > + local -n var=var_123 `var' is a local nameref with value var_123 > + : status is 0 > + local -p > var=var_123 > + : var is 123 Since var is a nameref, it expands to $var_123, which is 123 > + (( 1 )) > + shift > + local var=var_123 var doesn't get unset; it's still a nameref with value var_123. Setting the local attribute on an existing local variable doesn't unset any of the variable's attributes. You have to actually unset the variable to do that. > + local -n var=123 > ./x.sh: line 10: local: `123': invalid variable name for name reference So now you try to assign `123' as the value of a nameref. That would cause subsequent attempts to assign to var to attempt to create and assign to a variable named `123', which is invalid. Bash-4.3 didn't have enough error checking and would create variables with invalid names in situations like this. > + : status is 1 > + local -p > var=var_123 This is probably where the confusion comes. `local -p' doesn't print other variable attributes. If you had used `declare -p | grep var=' between the two calls to `local' you would have seen that `var' had the nameref attribute. > + : var is 123 > + (( 0 )) Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~ chet/
Re: Is this the expected behaviour for nameref in Bash 4.4 now?
On 10/20/16 2:45 PM, kjk...@gmail.com wrote: > set -x > > var_123=123 > f() { > while (( $# )); do > shift > local var=var_123 > local -n var=$var; : status is $? > local -p > : var is $var > done > } > > f one two > > > Running above script gives the follow output: > > + var_123=123 > + f one two > + (( 2 )) > + shift > + local var=var_123 > + local -n var=var_123 `var' is a local nameref with value var_123 > + : status is 0 > + local -p > var=var_123 > + : var is 123 Since var is a nameref, it expands to $var_123, which is 123 > + (( 1 )) > + shift > + local var=var_123 var doesn't get unset; it's still a nameref with value var_123. Setting the local attribute on an existing local variable doesn't unset any of the variable's attributes. You have to actually unset the variable to do that. > + local -n var=123 > ./x.sh: line 10: local: `123': invalid variable name for name reference So now you try to assign `123' as the value of a nameref. That would cause subsequent attempts to assign to var to attempt to create and assign to a variable named `123', which is invalid. Bash-4.3 didn't have enough error checking and would create variables with invalid names in situations like this. > + : status is 1 > + local -p > var=var_123 This is probably where the confusion comes. `local -p' doesn't print other variable attributes. If you had used `declare -p | grep var=' between the two calls to `local' you would have seen that `var' had the nameref attribute. > + : var is 123 > + (( 0 )) Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Is this the expected behaviour for nameref in Bash 4.4 now?
On 10/20/16 7:44 PM, Jack Kuan wrote: > Thanks for replying. > > I was expecting that in the second iteration of the loop, the > local var=var_123 command would make var a normal variable again with > value "var_123" This is the bad assumption. You didn't unset `var' before doing this, so it retains its local attribute and its nameref attribute. Trying to make a local variable from an already-local variable is a no-op. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Is this the expected behaviour for nameref in Bash 4.4 now?
Thanks for replying. I was expecting that in the second iteration of the loop, the local var=var_123 command would make var a normal variable again with value "var_123" and then the local -n var=$var would make var again a nameref to var_123. This seems to be the behavior of Bash 4.3. But anyway, it's easy to work around by introducing another variable rather than redefining the nameref var: set -x var_123=123 f() { while (( $# )); do shift local var=var_123 local -n var_ref=$var done } f one two On Thu, Oct 20, 2016 at 4:02 PM, Dan Douglas wrote: > Yes that was an intentional change to require valid identifiers. I can't > say it will always be that way or that there won't at some point be a > workaround. You can stiill use `${!param}' for now to refer to positional > parameters as you always could, but as usual that isn't useful if you > want to assign by reference. >
Re: Is this the expected behaviour for nameref in Bash 4.4 now?
Yes that was an intentional change to require valid identifiers. I can't say it will always be that way or that there won't at some point be a workaround. You can stiill use `${!param}' for now to refer to positional parameters as you always could, but as usual that isn't useful if you want to assign by reference.