I am looking for the "best way" or the accepted zsh idiom for creating and using functions that can return success or failure as well as a list or other text value.
Currently I am doing this:
function happy
{
local happy_list=( a b c d )
if true ; then
echo $happy_list
return 0
else
return 1
fi
}
function sad
{
local sad_list=( a b c d )
if false ; then
echo $sad_list
return 0
else
return 1
fi
}
echo happy
if happy_result=( $( happy ) ) ; then
echo '$?:' $?
echo '$#happy_result' $#happy_result
echo '$happy_result' $happy_result
echo '$happy_list:' $happy_list
else
echo '!?!?!?!?'
fi
echo
echo sad
if sad_result=( $( sad ) ) ; then
echo '!?!?!?!?'
else
echo '$?:' $?
echo '$#sad_result' $#sad_result
echo '$sad_result:' $sad_result
echo '$sad_list:' $sad_list
fi
which results in
happy
$?: 0
$#happy_result 4
$happy_result a b c d
$happy_list:
sad
$?: 1
$#sad_result 0
$sad_result:
$sad_list:
Is there a cleaner method? In particular the foo=( $( func ) )
syntax seems it could be improved since the list is already created in the func.
Update to moderator: I believe now this is a duplicate of this question and my preferred answer (if anyone cares) is this answer. The suggestion in Meta was to close and merge. I don't know how to do the merge. Can a moderator help me out?
CodePudding user response:
The usual idiom in zsh
is to return scalar results in the $REPLY
variable and array results in the $reply
array:
all-files-in() {
reply=( $^@/*(ND) )
(( $#reply ))
}
if all-files-in /foo /bar; then
print -r there were files: $reply
else
print -ru2 there were none
fi
Another approach is for the caller to specify the name of the variable where to store the result and use eval
or the P
parameter expansion flag to do indirect assignments.
all-files-in() {
eval $1='( $^@[2,-1]/*(ND) )
(( $#'$1' ))'
}
if all-files-in files /foo /bar; then
print -r there were files: $files
else
print -ru2 there were none
fi