Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

zsh: return associative array from function

Tags:

shell

zsh

How to return assciative arrays from zsh function?

I tried:

creatAARR() {
    declare -A AARR=([k1]=2 [k2]=4)
    return $AARR
}
creatAARR

But i get error:

creatAARR:return:2: too many arguments

What is the right way?

EDIT: I captured output to standard output, like how @chepner suggests, but the new variable doesn't seem to behave like an associative array:

creatAARR() {
    declare -A AARR=([k1]=2 [k2]=4)
    echo "$AARR"
}
declare -A VALL
NEW_ARR=$(creatAARR)
echo "$NEW_ARR" # 2 4
echo "k1: $NEW_ARR[k1]" # prints just k1:
return

Any suggestions?

like image 848
Alterecho Avatar asked Oct 28 '25 01:10

Alterecho


1 Answers

return accepts only an integer and sets the exit status of the function.

Shell commands cannot actually return values. If you want pass information to the caller of your function, you have a couple of options available to you:

  • You could print your return value, but this then relies on you to properly format your output and for the caller to correctly parse it. For associative arrays, there are so many ways that this can go wrong; I wouldn’t recommend doing this.
  • In Zsh, there is a convention that, to communicate a return value, a function can set $REPLY to a scalar value or $reply to an array. Unfortunately, there is no convention for passing associative arrays. You could, of course, put your key-value pairs simply as elements in the non-associative array $reply and then let the caller cast it to or wrap it in an associative array, but this would break the convention and thus might violate your caller's expectations.
  • The, in my opinion, best approach is to let the caller specify the name of an associative array, which you can then populate with values. This is also handy when you want to return multiple values of any type, since you can let the caller specify multiple variable names.

This last approach you can use as follows:

% creatAARR() {
  # Restrict $name to function scope.
  local name=$1

  # Delete $1, so $@ becomes the other args.
  shift

  # Assign elements to array. 
  set -A "$name" "$@"
}
% typeset -A AARR=()  # Declare assoc. array
% creatAARR AARR k1 2 k2 4
% typeset -p1 AARR    # Print details
typeset -A AARR=( 
  [k1]=2 
  [k2]=4 
)
like image 82
Marlon Richert Avatar answered Nov 02 '25 03:11

Marlon Richert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!