Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > gnu.bash.bug > #11791

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

From Oskar Maier <maier@imi.uni-luebeck.de>
Newsgroups gnu.bash.bug
Subject Re: Possible bug in 4.3.11: Nameconflict when when passing an array to a function
Date 2015-10-28 15:42 +0100
Message-ID <mailman.1204.1446043339.7904.bug-bash@gnu.org> (permalink)
References <5630A4FE.4020608@imi.uni-luebeck.de> <20151028135335.GL27325@eeg.ccf.org> <20151028142215.GM27325@eeg.ccf.org>

Show all headers | View raw


Dear Greg,

thank you for the extensive reply, I've already learned something new.

The code I've posted was just intended as a minimal working example 
without giving it to much thought, therefore please excuse the unquoted 
"arr[@]". Furthermore, the original source is a small collection of bash 
function, purely for private use, hence I did not took too much pain to 
make it portable.

The actual goal is hence not to print the array and I can solve the 
problem (while keeping the fragile hack) simply by removing the '-a' 
option of the 'local' statement.

The reason I posted here is simply to know a) what changed, b) why it 
changed, c) why there is a difference in the behaviour of 'local -a 
NAME' to 'local NAME' and d) if it possible constitutes a bug.

For the future, I will look out to avoid any hacks in my Bash-libraries. 
Lesson learned.

Best and thanks again,
Oskar

On 28.10.2015 15:22, Greg Wooledge wrote:
>> 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.)
>

-- 
Oskar Maier, M.Sc.
     Wissenschaftlicher Mitarbeiter

UNIVERSITÄT ZU LÜBECK
     INSTITUT FÜR MEDIZINISCHE INFORMATIK

     building 64, 2 floor, room 3
     Ratzeburger Allee 160
     23538 Lübeck
     Germany

     Tel +49 451 500 5645
     Fax +49 451 500 5610
     maier@imi.uni-luebeck.de

     www.imi.uni-luebeck.de

Back to gnu.bash.bug | Previous | Next | Find similar


Thread

Re: Possible bug in 4.3.11: Nameconflict when when passing an array to a function Oskar Maier <maier@imi.uni-luebeck.de> - 2015-10-28 15:42 +0100

csiph-web