【问题标题】:Closures get parent function name闭包获取父函数名
【发布时间】:2016-01-07 11:09:51
【问题描述】:

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

我做到了这一点,但有一个肮脏的黑客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_ 

【问题讨论】:

    标签: bash closures lexical-closures


    【解决方案1】:

    Bash 确实不是一种函数式编程语言。首先,函数不是一流的对象。你不能传递一个函数。您可以传递函数的name,但它只是一个名称;如果名称被赋予一个新值,那么旧值就会丢失。

    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
    

    【讨论】:

    • for @rici 1. 我没有问什么是“本地”; 2. 我没有收到“是否有任何解决方案可以使用某种 PARENT_FUNCNAME”的答案
    • @andrei 因为它没有答案。没有父作用域,因为 bash 并没有真正的作用域。如果您的问题是“我可以找到来电者的姓名吗?”然后问那个。但是无法找到定义当前函数的函数的名称,并且由于我试图解释的原因,您提出的解决方案将不起作用。
    • 好的,那我问。 @riki 我可以找到来电者的姓名吗?从“./docker_.sh docker_hello”获取调用者名称“docker_”?
    • @andrei: ${FUNCNAME[1]}
    猜你喜欢
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 2022-11-14
    • 2016-09-04
    • 2018-12-19
    • 2012-03-21
    • 2021-10-31
    • 2013-06-21
    相关资源
    最近更新 更多