|
From: | Pierre Gaston |
Subject: | Re: [Help-bash] Adding missing bash features for safely re-usable bash code |
Date: | Tue, 9 Apr 2013 09:08:48 +0300 |
On 04/08/2013 12:10 PM, Greg Wooledge wrote:A slight variation on that theme is to have the caller tell the function
> However, my personal preference for functions returning values (and this
> is not limited to strings; the same applies to integers larger than 255 or
> smaller than 0, or floating point values, or arrays) is to hard-code
> the variable "r" in both the caller and the callee:
>
> rand() {
> local max=$((32768 / $1 * $1))
> while (( (r=$RANDOM) >= max )); do :; done
> r=$(( r % $1 ))
> }
>
> caller() {
> local r
> rand 17
> if ((r < 10)); then ....
> fi
> }
>
> This gives the callee a place to store its return value, without requiring
> a subshell, and without requiring the re-parsing of an ASCII stream.
> If "r" is declared local in the caller, then its scope is limited to the
> caller and the callee. Otherwise, it's global. I get to choose.
>
> Of course this means I can't use the variable "r" for any other purpose.
> Not that I was going to. If you don't like that, you can use "___r" or
> whatever.
where to store the result:
rand() {
local max=$((32768 / $2 * $2))
local val
while (( (val=$RANDOM) >= max )); do :; done
val=$(( val % $2 ))
eval $1=$val
}
caller() {
local r
rand r 17
if ((r < 10)); then ...fi
}
Not shown is that you now have the burden of ensuring that the caller
doesn't pass in garbage for $1 which would be a disaster inside the
eval; but with the approach of telling a function where to put its
result, you no longer have to worry about choosing a naming convention
that the caller must follow for its called functions to work correctly.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[Prev in Thread] | Current Thread | [Next in Thread] |