VimL / Vimscript: как получить доступ к локальной переменной внешней функции из ее внутренней функции? - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть функция следующего вида:

function! s:my_function(dict_arg)
    let darg = copy(a:dict_arg)

    func! my_inner_func(cond)
        if a:cond ==# 'a'
            execute darg.a
        elseif a:cond ==# 'b'
            execute darg.b
        elseif a:cond ==# 'c'
            execute darg.c
        endif
    endfunc

    return function('my_inner_func')
endfunc

Где аргумент, передаваемый параметру dict_arg, будет иметь некоторый dict с ключами a, b и c, сих соответствующие значения являются строками, представляющими команды Ex, которые будут выполняться в зависимости от конкретного cond (условия).

Цель внешней функции s:my_function - создать Funcref, который будет выполнять соответствующую команду Ex(darg.a, darg.b или darg.c) на основе cond, который сам определяется в других местах другими переменными.

Так что моя проблема в том, что я не знаю, какссылаться на локальную переменную darg, определенную в области действия s:my_function, изнутри my_inner_func. Когда вызывается функция, я получаю ошибку E121: Undefined variable: darg. Это также не работает (та же ошибка), если я не определяю локальную переменную darg, а вместо этого просто пытаюсь сделать, например, execute a:dict_arg.b.

Я могу обойти это, определив darg быть глобальным, как в let g:darg = copy(a:dict_arg), а затем делать execute g:darg.a. Но, конечно, я бы хотел этого избежать.

В чем-то вроде Python этот тип разрешения лексических областей является автоматическим. Но VimL это хорошо .. VimL. Любая помощь или указатели будут оценены.

1 Ответ

2 голосов
/ 07 ноября 2019

В чем-то похожем на Python этот тип разрешения лексических областей является автоматическим

В VimScript, кроме лямбда-выражений, это руководство . Вы должны явно добавить ключевое слово closure:

func! my_inner_func(cond) closure
    ...
endfunction

Цель внешней функции s: my_function - создать Funcref, который будет выполнять соответствующую команду Ex (darg.a, darg. b или darg.c) на основе cond, который сам определяется в других местах другими переменными.

IMO, лучше использовать «частичное».

function! InnerFunc(foo, bar, baz)
    ...
endfunction
...
let OuterFunc = function('InnerFunc', ["FOO", "BAR"])
call OuterFunc("BAZ")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...