bug-bash
[Top][All Lists]
Advanced

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

Re: Incorrect / Inconsistent behavior with nameref assignments in functi


From: Koichi Murase
Subject: Re: Incorrect / Inconsistent behavior with nameref assignments in functions
Date: Sun, 30 Aug 2020 09:59:20 +0900

2020-08-29 14:46 Binarus <lists@binarus.de>:
> I am wondering when debian will include bash 5.1. It looks like
> debian testing and debian unstable are on bash 5.0, so it will
> probably take several years.

Actually the problem of the function `Dummy' will not be solved even
in bash 5.1.  There is another but similar problem with your function.
A user might specify `namerefArray' as the name of an outer array,
which results in a circular-reference error.

  $ cat testR2c.sh
  function Dummy {
    local -n namerefArray="$1"
    local -a -i myArray=("${namerefArray[@]}")
    local -p
  }
  declare -a -i namerefArray=('1' '2' '3')
  Dummy namerefArray

  $ bash-5.1-alpha testR2c.sh
  testR2c.sh: line 4: local: warning: namerefArray: circular name reference
  testR2c.sh: line 4: warning: namerefArray: circular name reference
  testR2c.sh: line 5: warning: namerefArray: circular name reference
  testR2c.sh: line 5: warning: namerefArray: circular name reference
  declare -a myArray=([0]="1" [1]="2" [2]="3")
  declare -n namerefArray="namerefArray"

If you want to work around the problem, there are several ways.

* One of the simplest ways is to use different variable names as
  already suggested by other people.  However, when the variable name
  is not under control for some reason (that, e.g., the functon is
  provided to users who may use it in an arbitrary way, or it imports
  different shell-script frameworks), the probability of the name
  collision is not 0%.

* Another way is to copy to the local array only when the name is
  different from `myArray':

  function Dummy {
    [[ $1 == myArray ]] ||
      eval "local -a myArray=(\"\${$1[@]}\")"
    declare -p myArray
  }

  When you want to add `-i' attribute to the array or to modify the
  array without affecting the original outer array, you may first save
  the value to another local array and next copy the array to the
  array that you want to edit.

  function Dummy {
    [[ $1 == inputArray ]] ||
      eval "local -a inputArray=(\"\${$1[@]}\")"
    local -ia myArray=("${inputArray[@]}")
    declare -p myArray
  }

* If you want to use namerefs to eliminate the use of `eval', maybe
  you could do like the following but I think it is more natural and
  readable to use eval:

  function Dummy {
    [[ $1 == refArray ]] || local -n refArray=$1
    [[ $1 == inputArray ]] || local -i inputArray=("${refArray[@]}")
    local -ia myArray=("${inputArray[@]}")
    declare -p myArray
  }

Best regards,

Koichi



reply via email to

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