🔤 Zsh Native Scripting Handbook
Information
@ is about keeping array form
How do access all array elements in a shell? The standard answer: use @ subscript, i.e. ${array[@]}. However, this is the Bash & Ksh way (and with the option KSH_ARRAYS, Zsh also works this way, i.e. needs @ to access the whole array). Z shell is different: it is a $array that refers to all elements anyway. There is no need for the @ subscript.
So what use has @ in the Zsh-world? It is: "keep array form" or "do not join". When is it activated? When the user quotes the array, i.e. invokes "$array", he induces joining of all array elements (into a single string). @ is to have elements still quoted (so empty elements are preserved), but not joined.
Two forms are available, "$array[@]" and "${(@)array}". The first form has an additional effect – when an option KSH_ARRAYS is set, it indeed induces referencing to the whole array instead of a first element only. It should then use braces, i.e. ${array[@]}, "${array[@]}" (KSH_ARRAYS requirement).
In practice, if you'll use @ as a subscript – [@], not as a flag – ${(@)...}, then you'll make the code KSH_ARRAYS-compatible.
extended_glob
Glob-flags #b and #m require setopt extended_glob. Patterns utilizing ~ and ^ also require it. Extended-glob is one of the main features of Zsh.
Constructs
Reading a file
typeset -a lines
lines=( "${(@f)"$(<path/file)"}" )
This preserves empty lines because of double-quoting (the outside one). @-flag is used to obtain an array instead of a scalar. If you don't want empty lines preserved, you can also skip @-splitting, as is explained in the Information section:
typeset -a lines
lines=( ${(f)"$(<path/file)"} )
Note: $(<...) construct strips trailing empty lines.
Reading from stdin
This topic is governed by the same principles as the previous paragraph (Reading a file), with the single difference that instead of the substitution "$(<file-path)" the substitution that should be used is "$(command arg1 ...)", i.e.:
typeset -a lines
lines=( ${(f)"$(command arg1 ...)"} )
This will read the command's output into the array lines. The version that does @ splitting and retains any empty lines are:
typeset -a lines
lines=( "${(f@)$(command arg1 ...)}" )