[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RFE: Fix the name collision issues and typing issues with namerefs, impr
RFE: Fix the name collision issues and typing issues with namerefs, improve various issues for function libraries
Wed, 14 Jun 2017 12:04:35 -0400
This is relevant to my interests!
So first off, the circular reference problem with "declare -n"
apparently doesn't exist in Korn Shell: If you "typeset -n x=$1", and
$1 is "x", it's not a circular reference. The nameref seems to take
the origin of the name into account when creating the nameref: If $1
is used to provide the name for a nameref within a function, then the
nameref refers to a variable in the scope of the function's caller.
But if the name for the nameref is taken from another parameter, or a
string literal, then the variable is drawn from the scope of the
function itself. It seems a little "black magic" in a way but it has
the benefit of neatly matching some important common use-cases. I
think Bash should either adopt something similar, or provide another
mechanism to exclude function-local variables from nameref
...And I could be wrong here (as I haven't used namerefs much in bash)
but it seems you can't use a nameref to change the type of a
variable... For instance if "x" is local to f1, and f1 calls "f2 x",
and f2 declares a nameref that resolves to its argument "x", f2 cannot
then change "x" to an associative array, for instance. The caller has
to declare the variable with the proper type before passing it into
the function as a nameref.
Regarding return values, there's a couple ways of looking at this:
First, a common way of dealing with the situation is to have functions
emit their results to stdout, and then capture the data with command
substitution. This is a bit problematic because command substitution
occurs in a subshell environment. (This is actually mandated in Posix,
it seems - which is unfortunate, because there's actually no need for
it to be a subshell environment! In Korn Shell, it's not... Command
substitution is evaluated in the main shell environment - which struck
me as odd at first, but it actually makes sense for these kinds of
scenarios, where you want to run something that has a side-effect, and
capture its output.) This means a function call or built-in can't
create side-effects in the shell environment (setting environment
variables or open/close files) AND emit a result on stdout for
capture. It's strictly one or the other.
Second, with namerefs in the picture, one could use them to tell a
function where to store its return value. It doesn't look "functional"
but it gets the job done, right? But again, there's the various
problems with namerefs in Bash presently. Name collisions can lead to
circular references, and the type of the var can't be changed using
Finally, of course... Functions could simply "return" values by
populating a variable in the caller's scope. I don't think it's a
And finally, with respect to creating Bash "libraries" of functions:
The problem of namespace pollution could be largely solved by
supporting some form of namespaces to contain the declarations that
are needed only locally. (Current versions of ksh have a whole OO
system, meaning a library's footprint in global namespace can be very
----- Original Message -----
From: "Greg Wooledge" <address@hidden>
Sent:Wed, 14 Jun 2017 08:43:14 -0400
Subject:Re: RFE: Please allow unicode ID chars in identifiers
On Tue, Jun 13, 2017 at 04:58:59PM -0700, L A Walsh wrote:
> Forgive me if I'm misremembering, but hasn't Greg argued against
> the ability to supply "libraries" of re-usable scripts due to
> the ease with which names could conflict with each other and cause
> script incompatibilities?
Namespace collisions are certainly an issue, yes. But my primary
argument against trying to write "libraries" in bash has always been
the limitations of bash's functions.
1) You can't return values from them (making them more like
than actual functions).
2) You can't pass variables by reference. Therefore:
3) You can't pass the name of a variable in which you'd like to
a value from the function, to work around point 1.
4) You can't pass an array by name. You have to pass every single
element separately, losing the indices in the process.
"declare -n" looks like it should address point 2, but it doesn't
do so safely. It only works if you magically choose a name (within
the function) that the caller does NOT choose (outside the function).
In fact, the caller's variable name must not match ANY local variable
of the function, or it breaks.
See examples at
If your function is recursive (is its own caller), then you're simply
doomed -- you can't avoid having the same name used in the caller and
callee, because they're both the same piece of code. You might be
hack up a global indexed array of return values, and then each
of the recursive function can use its recursion depth as an index
this array to retrieve its return value. That's the best I can think
- RFE: Fix the name collision issues and typing issues with namerefs, improve various issues for function libraries,