bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

nameref and referenced variable scope, setting other attributes (was "lo


From: Zachary Santer
Subject: nameref and referenced variable scope, setting other attributes (was "local -g" declaration references local var in enclosing scope)
Date: Sun, 10 Mar 2024 19:29:49 -0400

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 <zsanter@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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]