[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:
x=global
foo() { declare -n xr=x ; bar; }
bar() { local x=bar ; xr=new ; echo "after xr=new xr is $xr"; }
foo
echo "x at top level is $x"
Output:
> 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
page.
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.
-Mark
- a nameref may resolve to different variables in assignment and parameter expansion,
Mark March <=