Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: msys Compiler: gcc Compilation CFLAGS: -march=nocona -msahf -mtune=generic -O2 -pipe -D_STATIC_BUILD uname output: MINGW64_NT-10.0-19045 Zack2021HPPavilion 3.4.10.x86_64 2024-02-10 08:39 UTC x86_64 Msys Machine Type: x86_64-pc-msys
Bash Version: 5.2 Patch Level: 26 Release Status: release Description: On Sun, Mar 10, 2024 at 3:55 PM Zachary Santer <zsan...@gmail.com> wrote: > > Relatedly, how would one set attributes on a variable declared in a > calling function? 'readonly' and 'export' can do it for their > respective attributes, but otherwise, I think you just can't. Second-guessed myself. The manual says about 'declare -n': -n Give each name the nameref attribute, making it a name reference to another variable. That other variable is defined by the value of name. All references, assignments, and attribute modifications to name, except those using or changing the -n attribute itself, are performed on the variable referenced by name's value. The nameref attribute cannot be applied to array variables. local, when called on a nameref variable referencing a variable declared in a calling function, creates a new local variable named the same as the value of the nameref variable. Given the above, I would expect it to instead allow the setting of attributes and value of a variable declared in a calling function. Additionally, a nameref variable referencing a variable declared in a calling function hides that variable in the scope of the function where the nameref variable is declared. Repeat-By: $ cat ./nameref-what #!/usr/bin/env bash func_1 () { local var_1='BREAD' local var_2='ICE CREAM' local var_3='EGG' func_2 printf '%s\n' "func_1:" local -p var_1 local -p var_2 local -p var_3 } func_2 () { local -n nameref_1=var_1 local -l nameref_1 nameref_1='TOAST' local -nl nameref_2='VAR_2' nameref_2='MILKSHAKE' local -n nameref_3='var_3' nameref_3='soufflé' local var_4='GROUND BEEF' local -n nameref_4='var_4' local -l nameref_4 printf '%s\n' "func_2:" local -p nameref_1 local -p var_1 local -p nameref_2 local -p var_2 local -p nameref_3 local -p var_3 local -p nameref_4 local -p var_4 } func_1 $ ./nameref-what func_2: declare -n nameref_1="var_1" declare -l var_1="toast" declare -nl nameref_2="var_2" ./nameref-what: line 29: local: var_2: not found declare -n nameref_3="var_3" ./nameref-what: line 31: local: var_3: not found declare -n nameref_4="var_4" declare -l var_4="GROUND BEEF" func_1: declare -- var_1="BREAD" declare -- var_2="MILKSHAKE" declare -- var_3="soufflé" Because var_1 wasn't declared in the scope of func_2, I was expecting the var_1 in func_1 to gain the -l attribute and the value 'toast'. local instead declaring a new local variable var_1 in the scope of func_2 doesn't make as much sense. Setting the value of nameref_2 to "var_2" because of nameref_2's -l attribute makes sense, but I'm surprised that var_2 is now hidden in the scope of func_2. And then nameref_3 and var_3 show that that would've happened regardless of -l. Indeed, there is no way to set attributes other than readonly and export on a variable declared in a calling function.