闭包获取父函数名称

时间:2015-10-09 13:16:55

标签: bash closures lexical-closures

Bash是“一种函数式编程语言”,它没有类。一世 设法使用Closures封装,但我也想做一些 内省找到docker_父/超/基函数(如果你知道添加 评论来正确定义这个。)

我管理了这个,但是有一个肮脏的黑客super=${FUNCNAME}。有什么解决方案吗? 使用PARENT_FUNCNAME种?我有这样的文件 docker_.sh

#!/usr/bin/env bash
function docker_ {
    local super=${FUNCNAME}
    function hello {
        echo "INFO" "do ${super}${FUNCNAME}"
    }
    function install {
        echo "INFO" "do ${super}${FUNCNAME}"
        #sudo curl -sSL https://get.docker.com/ | sh || exit 1
    }
    function run {
        echo "INFO" "do ${super}${FUNCNAME}"
        #docker run -d -p 3306:3306 ${DOCKER_IMAGE_NAME} /docker.sh run_mysql
    }
    ${@}
}
${@}

得到了一些结果:

$ ./docker_.sh docker_ hello
INFO do docker_hello

$ ./docker_.sh docker_ run
INFO do docker_run

$ ./docker_.sh docker_ install
INFO do docker_install

解决

使用

${FUNCNAME[1]}
${FUNCNAME[@]:0:${#FUNCNAME[@]}-1} get all list beside main

代码:

#!/usr/bin/env bash
function docker_ {
    function hello {
        echo "INFO" "do ${FUNCNAME[1]} ${FUNCNAME}"
    }
    function install {
        echo "INFO" "do > ${FUNCNAME[@]:0:${#FUNCNAME[@]}-1} "
        #sudo curl -sSL https://get.docker.com/ | sh || exit 1
    }
    function run {
        echo "INFO" "do > ${FUNCNAME[@]:0:${#FUNCNAME[@]}-1} "
        #docker run -d -p 3306:3306 ${DOCKER_IMAGE_NAME} /docker.sh run_mysql
    }
    ${@}
}
${@}

得到了一些结果:

    ➜ ./docker_.sh docker_ hello  
    INFO do docker_ hello
    ➜ ./docker_.sh docker_ install
    INFO do > install docker_ 
    ➜ ./docker_.sh docker_ run    
    INFO do > run docker_ 

1 个答案:

答案 0 :(得分:1)

Bash真的不是一种函数式编程语言。首先,函数不是一流的对象;你不能传递一个函数。你可以传递一个函数的名称,但它只是一个名字;如果名称被赋予新值,则旧值将丢失。

Bash没有词法范围:bash范围是动态的。与任何其他命令一样,local命令是一个命令。它不是语法。如果未执行,则名称不是本地名称。例如:

f() {
  if [[ $1 == local ]]; then local myvar=local; fi
  myvar=changed
}

$ var=original
$ f local
$ echo $myvar
original
$ f global
$ echo $myvar
changed

bash没有闭包。您可以在函数内部定义函数,但是如此定义的函数不会带有范围。

$ g() {
>   local myvar=inner
>    f() { echo $myvar; }
>    f
> }
$ myvar=outer
$ g
inner
$ f
outer
$ h() { local myvar=inside_h; f; }
$ h
inside_h
$ f
outer