[Top][All Lists]

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

a nameref may resolve to different variables in assignment and parameter

From: Mark March
Subject: a nameref may resolve to different variables in assignment and parameter expansion
Date: Thu, 6 Jan 2022 18:31:55 +0000 (UTC)

It appears that the same initialized nameref variable may refer to variables in 
different scopes depending on the context where it is used. When used in an 
assignment, a nameref will look for the variable it references starting at the 
scope where the nameref itself was found, which may be below the current scope. 
In a parameter substitution a nameref will always start looking for its target 
in the current scope.

This leads to unintuitive behavior where a variable appears to not change its 
value after an assignment. Example:

foo() { declare -n xr=x ; bar; }
bar() { local x=bar ; xr=new ; echo "after xr=new xr is $xr"; }
echo "x at top level is $x"


> after xr=new xr is bar
> x at top level is new

This is with bash-5.1.8 and 5.1.16.

It is completely unexpected that "xr=new; echo $xr" may print something other 
than "new". If this is intentional, I would be curious to know the rationale. 
It would also help a lot if you spelled out the nameref lookup rules in the man 

On a side note, my personal preference would be to have namerefs remember the 
scope of the variable that they reference (once that scope is known), and 
always resolve to that same SHELL_VAR, until unset, instead of looking up a 
SHELL_VAR by name, as is the current behavior. Among other things, this would 
solve the dreaded conflict between namerefs and dynamic scoping that has been 
discussed extensively on this list, most recently inĀ  
https://lists.gnu.org/archive/html/bug-bash/2020-08/msg00206.html. I use 
namerefs extensively in a fairly large Bash code base for parameter passing, 
and I have to use fairly elaborate work-arounds to detect local variables 
shadowing outer-scope variables that the function operates on via namerefs.


reply via email to

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