bug-bash
[Top][All Lists]
Advanced

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

Re: Possible bug in 4.3.11: Nameconflict when when passing an array to a


From: Greg Wooledge
Subject: Re: Possible bug in 4.3.11: Nameconflict when when passing an array to a function
Date: Wed, 28 Oct 2015 10:22:15 -0400
User-agent: Mutt/1.4.2.3i

> On Wed, Oct 28, 2015 at 11:35:42AM +0100, Oskar Maier wrote:

> #!/bin/bash
> 
> function printarray1 () {
>   local -a arr=("${!1}")
>   echo "${arr[@]}" # printing the complete array
>   echo "${arr[9]}" # just to check if it is really recognized as an integer 
> indexed array
> }
[...]
> printarray1 arr[@]


I have a few immediate comments:

1) Your unquoted arr[@] is subject to filename expansion (globbing)
   and could be transformed to arr@ if you happen to have a file by
   that name in the current directory.  Quote it.

2) You're using that repulsive string="array[@]" ... ${!string} trick
   that someone discovered once upon a time and which has spread like
   a virus.  This may give the illusion of being able to pass an array
   to a function by name, but as you've learned, it falls apart when
   the function's local variable name is the same as the caller's name.
   Even bash 4.3's namerefs (declare -n) fall apart in this same
   situation.  There IS NO WAY to pass an array to a function by name
   safely in bash.  Everything you try is just a fragile hack that will
   fail one day.

   You've made it even more repulsive by not hiding the [@] trickery
   inside the function, but instead forcing the caller to be aware of it.

3) Using both "function" and "()" is redundant.


Now, as for the changes from bash 4.2 to 4.3, I don't know the whole
answer.  Here are some of the changes from the CHANGES file:

u.  There are changes to the expansions peformed on compound array assignments,
    in an effort to make foo=( [ind1]=bar [ind2]=baz ) identical to
    foo[ind1]=bar foo[ind2]=baz.

hhhh. Fixed a bug that caused `declare' and `test' to find variables that
      had been given attributes but not assigned values.  Such variables are
      not set.

Those might be related, or not.

In any case, fragile hacks may stop working when you upgrade software.
That is the nature of fragile hacks, and it's why you should stick to
actual documented features.

You're trying to make bash do things it simply cannot do.

If the ACTUAL goal is to print the contents of an array (i.e. if the
actual goal is not "I'm trying to find a way to pass an array to a
function by name"), then do not call a function.  Just use an inline
command, such as one of these:

  echo "${myarray[@]}"
  declare -p myarray
  printf "<%s> " "${myarray[@]}"; echo

If you want to hide the details, you could make an alias, and turn on
the shopt that allows aliases in scripts.  (I wouldn't do this; I'd just
leave the inline command as is.)



reply via email to

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