Reputation: 1050
I have a function of the following form:
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
Where the argument passed to the dict_arg
parameter will be some dict keyed with a
, b
and c
, with their respective values being strings representing Ex commands that will be executed depending on the specific cond
(condition).
The purpose of the outer function s:my_function
is to generate a Funcref that will execute the appropriate Ex command (darg.a
, darg.b
or darg.c
) based on the cond
, which is itself determined elsewhere by other variables.
So my problem is that I don't know how to reference the local variable darg
defined in the scope of s:my_function
from within my_inner_func
. When the function is called, I get the error E121: Undefined variable: darg
. It also doesn't work (same error) if I don't define the local variable darg
, and instead just try to do execute a:dict_arg.b
for instance.
I can get around it by defining darg
to be global, as in let g:darg = copy(a:dict_arg)
, then later doing execute g:darg.a
. But of course, I'd like to avoid that.
In something like Python, this type of lexical scope resolution is automatic. But VimL is well.. VimL. Any help or pointers will be appreciated.
Upvotes: 1
Views: 572
Reputation: 15186
In something like Python, this type of lexical scope resolution is automatic
In VimScript, except lambdas, it's manual. You have to explicitly add closure
keyword:
func! my_inner_func(cond) closure
...
endfunction
The purpose of the outer function s:my_function is to generate a Funcref that will execute the appropriate Ex command (darg.a, darg.b or darg.c) based on the cond, which is itself determined elsewhere by other variables.
IMO, it's better to use "a partial".
function! InnerFunc(foo, bar, baz)
...
endfunction
...
let OuterFunc = function('InnerFunc', ["FOO", "BAR"])
call OuterFunc("BAZ")
Upvotes: 3