shellzsh

Zsh Variadic Assignment


I want to be able to perform a "variadic assignment" in zsh.

I thought the following would work, but I get parse error near =("${(@)1}")'`:

variadic() {
  local a b
  (a, b)=("${(@)1}")
  echo "$a, $b!"
}

$ variadic Hello world  # Desired output: Hello, world!

(a, b)=($1 $2) results in a similar error.

Thank you


Solution

  • Multi-variable assignment is available in for loops in zsh, so one (unusual-looking) option is to use that and then bypass the loop body:

    #!/usr/bin/env zsh
    
    variadic() {
        local a b
        for a b; break
        print -r -- "$a, $b!"
    }
    
    variadic Hello world
    #=> Hello, world!
    
    variadic Hello world with extra words
    #=> Hello, world!
    
    variadic Hello
    #=> Hello, !
    

    The function above uses a shortened form of the for loop, and also uses the default list ($@).
    This equivalent version has the full loop syntax:

    variadicfull() {
        local a b
        for a b in "$@"; do
            break
        done
        print -r -- "$a, $b!"
    }
    

    A more conventional assignment also works:

    nonvariadic() {
        local a=$1 b=$2
        print -r -- "$a, $b!"
    }