help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Adding missing bash features for safely re-usable bash c


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 Mon, Apr 8, 2013 at 10:07 PM, Eric Blake <address@hidden> wrote:
On 04/08/2013 12:10 PM, Greg Wooledge wrote:
> 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.

A slight variation on that theme is to have the caller tell the function
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

 
Besides passing garbage, you can also pass the name of one of
the  local variable used in the function, eg "rand max 17".
So you also need to create unique local variables names 
or play with the positional parameters.

Hopefully, nameref will allow to solve these problems.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]