bug-bash
[Top][All Lists]
Advanced

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

Re: Incorrect / Inconsistent behavior with nameref assignments in functi


From: Oğuz
Subject: Re: Incorrect / Inconsistent behavior with nameref assignments in functions
Date: Fri, 28 Aug 2020 18:37:00 +0300

28 Ağustos 2020 Cuma tarihinde Greg Wooledge <wooledg@eeg.ccf.org> yazdı:

> On Fri, Aug 28, 2020 at 10:56:34AM +0200, Binarus wrote:
> > #!/bin/bash
> >
> > function Dummy() {
> >
> >   local -n namerefArray="$1"
> >   local -a -i myArray=("${namerefArray[@]}")
> >
> >   local -p
> > }
> >
> > declare -a -i myArray=('1' '2' '3')
>
> You've got a local variable with the same name as the global variable
> that you're attempting to pass by reference.  This will not work.
>
>
These scripts yield identical output on bash-5.1 though.


> Namerefs (declare -n) in bash are *not* like uplevel commands in Tcl.
> They cause the referenced variable name to be evaluated just like any
> other variable would be, starting at the current function scope, then
> going up to the caller, and so on.
>
> If you want to use namerefs in a function in bash, you MUST go out of
> your way to minimize the chances of a collision between the caller's
> variable refererance and ANY local variable of the function.  Not just
> the nameref itself, but any other incidental variables used in the
> function.  (As you aptly demonstrated here.)
>
> So, you can't write functions like this:
>
> func1() {
>   declare -n ref="$1"
>   local i
>   ...
> }
>
> Instead, you need crazy things like this:
>
> func1() {
>   declare -n _func1_ref="$1"
>   local _func1_i
>   ...
> }
>
>
This doesn't make the slightest sense. What is the point of having local
variables then?


> And then you just have to pray that the caller respects you enough not
> to use variables named with _func1_ prefixes.
>
> There is no 100% bulletproof solution to this issue.
>
> See also <https://mywiki.wooledge.org/BashProgramming#Functions>.
>
>

-- 
Oğuz


reply via email to

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