I am confused by the differing behavior of zparseopts in two different versions of zsh. Basically I am trying to set a list of default option values in an associative array and overwrite these defaults with any options specified on the command line. The below code works well for zsh 5.0.6 but behaves oddly for 4.3.6-- specifically, in zsh 4.3.6, my whole array of defaults is overwritten if a single key is overwritten.


typeset -A opts
--opt1 a
--opt2 b

zparseopts -A opts -K -- -opt1: -opt2:
echo ${(k)opts}

Running the script

$ myscript 
--opt1 --opt2  # both zsh 4.3.6 and 5.0.6

$ myscript --opt1 x
--opt1 --opt2  # zsh 5.0.6; element of array is replaced
--opt1         # zsh 4.3.6; adding an element overwrites the whole array, no more opt2

This behavior is confusing because 4.3.6 and 5.0.6 have identical entries for the -K option to zparseopts:

-K With this option, the arrays specified with the -a and -A options and with the `=array' forms are kept unchanged when none of the specs for them is used. This allows assignment of default values to them before calling zparseopts.

1 Answer 1


Replace the last line of your script with echo ${(kv)opts}. Running with 4.3.6 and 5.0.6 should show that 4.3.6 interprets -K to reset opts if any options are given, while 5.0.6 only resets opts[--opt1] when --opt1 is used (leaving --opt2 or any other entry alone).

(Note this appeared to change sometime between 5.0.2 and 5.0.6; you might want to ask on the zsh-workers mailing list to confirm.)=

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .