Hap*_*ace 4 zsh array function
I have this function,
rpargs () {
local i
args=()
for i in "$@"
do
test -e "$i" && args+="$(realpath --canonicalize-existing -- "$i")" || args+="$i"
done
}
Run Code Online (Sandbox Code Playgroud)
And I want to return args
. The only ways I can think of are either to printf '%s\0'
and then split it via expansion flags (0@)
, or to use a global like the code above.
zsh
's return
builtin can only return a 32bit signed integer like the _exit()
system call. While that's better than most other Bourne-like shells, that still can't return arbitrary strings or list of strings like the rc
/es
shells. The return status is more about returning a success/failure indication.
Here, alternatively, you can have the function take the name of the array to fill in as argument, like:
myfunc() {
local arrayname=$1; shift
# ...
eval $arrayname'=("$elements[@]")'
# the returned $? will be 0 here for success unless that eval command
# fails.
}
myfunc myarray other args
Run Code Online (Sandbox Code Playgroud)
Your printf '%s\0'
approach wouldn't work for array elements that contain NULs.
相反,您可以使用qq
参数扩展标志来引用输出上的元素,以及输入上的z
(解析引号)和Q
(删除引用),例如:
myfunc() {
# ...
print -r -- ${(qq)elements}
}
myarray=("${(@Q)${(z)$(myfunc)}}")
Run Code Online (Sandbox Code Playgroud)
但除了不太清晰之外,它的效率也较低,因为它意味着myfunc
除了引用/取消引用之外,还需要分叉一个进程并通过管道传输输出。
惯用的方法是只使用reply
数组。如果需要,您可以使用该(P)
标志并在其名称传递给函数的数组中返回:
myfunc() {
local arrayname=${1:-reply}; shift
# ...
: ${(PA)arrayname::="${args[@]}"}
}
Run Code Online (Sandbox Code Playgroud)