3

After reading this answer by Kusalananda I got some sense about what is a variable-attribute, yet I miss what is a "name-reference" (type?) of a variable-attribute, what is it using for, why would one want to use it in a Bash script,

I tried to Google the term "name reference" (without quote marks) but I didn't find a wiki article on this term.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

2 Answers2

6

Example: Pass two separate arrays to a function.

#!/bin/bash

foo () {
    declare -n array1="$1"
    declare -n array2="$2"

    echo 'The 1st array:'
    printf '\t%s\n' "${array1[@]}"

    echo 'The 2nd array:'
    printf '\t%s\n' "${array2[@]}"
}

a=( 1 2 3 )
b=( a b c )

foo a b

Testing:

$ bash script.sh
The 1st array:
        1
        2
        3
The 2nd array:
        a
        b
        c

Doing the same thing without the use of name reference variables would have been difficult and would probably involve either changing the function to only ever handle one array each call, or having it take the number of elements in each of the two arrays as extra arguments, or using eval in some way (which is difficult to do correctly).

With the use of name reference variables in the function, no esoteric syntax is needed to use the data in the arrays passed (as names) to the function, and the function is able to use the name reference variables as ordinary arrays.

In the function, the two variables array1 and array2 references, i.e. can be used as, the variables passed by name in $1 and $2. They are name references.

This is similar to a "call by reference" in e.g. C++ I believe, but instead of using &variable on the calling side (as in C++), the receiving side declares a local variable as a reference.

Kusalananda
  • 333,661
  • Hi, any chance to explain it without declare, because I don't understand declare at all? –  May 31 '19 at 21:12
  • @JohnDoea Your question was about setting attributes on variables, in particular the name-reference attribute. This is done with declare. To explain how to make a name-reference variable in bash without mentioning and using declare is impossible. – Kusalananda May 31 '19 at 21:56
5

Some of the attributes are more like what would be called variables types in other languages. Name references are such a "type". Like references in many languages, access to the variable actually accesses some other variable (the one referenced). The only exception is when using declare -n to set what variable is referenced, or declare -p to show it.

So, e.g.

foo=123
declare -n ref=foo      # set what 'ref' points to
ref=456                 # set the value of 'foo'
echo "$foo $ref"        # both are the value of 'foo'

would print 456 456.

However, declare -p will show that ref is a reference to foo, and foo the variable with an actual value.

$ declare -p foo ref
declare -- foo="456"
declare -n ref="foo"                   
ilkkachu
  • 138,973
  • Sadly I cannot understand the answer: I don't understand why to use name references, set what 'ref' points to why? echo "$foo $ref" what problem it solves? –  Apr 21 '19 at 04:09