[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.)