[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Passing variables by reference conflicts with local
From: |
Freddy Vulto |
Subject: |
Re: Passing variables by reference conflicts with local |
Date: |
Sun, 2 May 2010 13:35:59 +0200 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
Here's another revised version.
I figured I could use bash internal `printf -v' just before the `eval'
to check if the variable name is a valid identifier. This should be an
exceptional case, so I don't mind doing this at the end of the function
- checking just before the eval. Now it's also easy to see the eval is
safe (provided you don't make typos on the right hand side, see
http://mywiki.wooledge.org/BashFAQ/006, thanks).
I moved conflict checking to a central reusable function
"_blackbox_safe_vars()" because one needs to do this for *every* library
function which is returning variables by reference, in my opinion, unless
you're willing to obfuscate all your local variables and still wait for a
conflict to happen?
The code below works around the following bash caveats?:
- local variables conflict with variables to be returned by reference
- `local' only lists variables having a value
- `printf -v' can't be used to assign to an array
Here's the code:
# Check whether variable name(s) conflicts with local(s)
# Params: $1 Local var names (output of 'local')
# $* Variables to check
# Return: False (1) if error
_blackbox_safe_vars() {
local IFS=$'\n' l v
for l in $1; do
for v in "${@:2}"; do
[[ ${l%=*} == $v ]] && echo "ERROR: ${FUNCNAME[1]}:"\
"\`$v': conflicts with local" 1>&2 && return 1
done
done
return 0
}
# Check whether private function is being called by public interface
# Params: $1 Public function
# Return: False (1) if error
_blackbox_called_by() {
[[ ${FUNCNAME[2]} != $1 ]] && { echo "ERROR: ${FUNCNAME[1]}:"\
"MUST be called by $1()" 1>&2; return 1; } || return 0
}
# Private library function. Do not call directly. See blackbox()
_blackbox() {
_blackbox_called_by blackbox || return 1
local a b c d e f g h i j k=( foo "bar cee" )
# ...
# Lots of library code here, not more than one screen though ;-)
# ...
printf -v"$2" %s b # Return value
printf -v"$3" x && eval $3=\(\"\${k[@]}\"\) # Return array
return 0 # Return status
}
# Param: $1 input argument
# Param: $2 variable name to return value to
# Param: $3 variable name to return array value to
# Public library function
blackbox() {
# NOTE: Give all locals a value so they're listed with 'local'
local __2= __3= __x=
_blackbox_safe_vars "$(local)" "$2" "$3" || return 1
_blackbox "$1" __2 __3 # Call private
__x=$? # Catch status
printf -v"$2" %s "$__2" # Return value
printf -v"$3" x && eval $3=\(\"\${__3[@]}\"\) # Return array
return $__x # Return status
}
blackbox i a b; printf $'%s\n' $a "${b[@]}" # Outputs vars ok
blackbox i __2 __3 # Outputs error
d='ls /;true'; blackbox i "$d" "$d" # No oops
_blackbox a # Force public access
Freddy Vulto
http://fvue.nl/wiki/Bash:_passing_variables_by_reference
- Re: Passing variables by reference conflicts with local, Freddy Vulto, 2010/05/01
- Re: Passing variables by reference conflicts with local, Dennis Williamson, 2010/05/01
- Re: Passing variables by reference conflicts with local, Pierre Gaston, 2010/05/01
- Re: Passing variables by reference conflicts with local, Freddy Vulto, 2010/05/01
- Re: Passing variables by reference conflicts with local, Dennis Williamson, 2010/05/01
- Re: Passing variables by reference conflicts with local, Freddy Vulto, 2010/05/01
- Re: Passing variables by reference conflicts with local, Dennis Williamson, 2010/05/01
- Re: Passing variables by reference conflicts with local,
Freddy Vulto <=
- Re: Passing variables by reference conflicts with local, Dennis Williamson, 2010/05/02
- Re: Passing variables by reference conflicts with local, Freddy Vulto, 2010/05/03
- Re: Passing variables by reference conflicts with local, Freddy Vulto, 2010/05/04
- Re: Passing variables by reference conflicts with local, Chet Ramey, 2010/05/05
- Re: Passing variables by reference conflicts with local, Chet Ramey, 2010/05/04
- Re: Passing variables by reference conflicts with local, Chet Ramey, 2010/05/02
- Re: Passing variables by reference conflicts with local, Matthew Woehlke, 2010/05/03
Re: Passing variables by reference conflicts with local, Greg Wooledge, 2010/05/03