On Fri, Apr 09, 2021 at 08:17:52AM +0800, konsolebox wrote:
> On Fri, Apr 9, 2021 at 4:08 AM Greg Wooledge <[email protected]> wrote:
> > But apparently someone stumbled upon this trick, and passed it around,
> > and now there's a whole subculture of people who use this as a hack for
> > trying to pass array variables to functions by reference. (This hack
> > predates declare -n.)
>
> It's not a hack since indirection allows references to:
>
> 1) Digit-based parameters ($1, $2, etc.)
> 2) Special variables (which includes $@)
> 3) Valid array references (array[@] and array[1 + 1] are one of them)
> 4) Legal identifiers
>
> It's a definite shell feature despite lacking internal sanity checks.
Have you actually SEEN this? This is how people use it:
myfunc() {
# $1 is the name of an array we want to work with
tmp=$1[@] # And yes, they always name it "tmp".
for i in "${!tmp}"; do
...
done
}
How can you look at that code and call it anything other than a hack?
It's a piece of pure desperation. You can only READ the array, not write
to it. You can't do an index iteration, either -- only a value iteration.
And you still have all the same name collision issues that you'd get
with namerefs. This makes it genuinely inferior to using a nameref to
acheive the same goal:
myfunc() {
# $1 is the name of an array we want to work with
declare -n aref=$1
# Value iteration.
for i in "${aref[@]}"; do
...
done
# Index iteration.
for i in "${!aref[@]}"; do
...
done
# Writing.
aref[42]=hey
}
(Insert here all of the problems with name collisions, which are real,
but you should already know them.)