3

You're able to access the parent function name with ${FUNCNAME[1]} (In BASH, is it possible to get the function name in function body?). Is there a way to also access the parent function argument length (arity)?

So instead of this:

get() {
  [ "$#" != 2 ] && exit 1
}

You could do something like this:

get() {
  assert_arity 2
}

assert_arity() {
  local arity=${parent_function_arity}
  local value=$1
  [ "${arity}" != "${value}" ] && exit 1
}

Is that possible?

Community
  • 1
  • 1
Lance
  • 75,200
  • 93
  • 289
  • 503

3 Answers3

4

It is possible:

shopt -s extdebug

assert_arity() {
    local arity=${BASH_ARGC[1]}
    local value=$1
    [ "${arity}" != "${value}" ] && echo "nope"
}

BASH_ARGC is set only in extdebug mode. If it is, it is an array of the number of arguments of the whole call stack, with the current frame at index 0.

Renaud Pacalet
  • 25,260
  • 3
  • 34
  • 51
2

If all you want is a cleaner code you can pass the actual arguments to the assert_arity() function like this:

get() {
  assert_arity 2 "$@"
}

assert_arity() {
  local arity=$(( $# - 1 ))
  local value=$1
  [ "${arity}" != "${value}" ] && exit 1
}
vlp
  • 7,811
  • 2
  • 23
  • 51
0

If you set the extdebug shell option, the arities of the current call stack are stored in the array BASH_ARGC.

shopt -s extdebug

get () {
  assert_arty 2
}

assert_arity () {
  local arity=${BASH_ARGC[1]}  # 0 is us, 1 is the parent
  local value=$1
  (( arity != value )) && exit 1
}
chepner
  • 497,756
  • 71
  • 530
  • 681