Замыкания получают имя родительской функции

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 ответ

Решение

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

И у Баш нет закрытий. Вы можете определить функцию внутри функции, но определенная таким образом функция не несет с собой область действия.

$ 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
Другие вопросы по тегам