On Fri, Apr 09, 2021 at 08:17:52AM +0800, konsolebox wrote: > On Fri, Apr 9, 2021 at 4:08 AM Greg Wooledge <g...@wooledge.org> 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.)