将局部变量传递给eval中创建的函数,即: - viml中的闭包

时间:2013-08-23 17:59:01

标签: vim

我在运行时在execute/eval'字符串中创建动态函数。该函数是根据调用生成器函数时出现的不同变量构建的。生成器功能如下,

function! NewCallback(method, opts) 
  let my_opts = a:opts
  let function_name = "g:MyDynamicFunction_" . a:method

  let body  = "function! " . function_name . "(...)\n"
  let body .= "  echo 'running " . function_name . "'\n"
  let body .= "  echo my_opts\n"
  let body .= "endfunction"

  execute body
  return function_name
endfunction

我正在使用此功能,如下所示。首先,我创建一个回调,它给出了作为结果生成的函数的名称。然后我用以下方法调用此函数:

let callback = NewCallback('foo', { 'a': 1, 'b': 2 })
execute(":call " . callback . "(1, 2, 3)")

我遇到的问题是在生成的函数内访问NewCallback范围内的变量。在这里,我需要访问生成的函数my_optsNewCallback本地的MyDynamicFunction_foo

目前它给了我undefined variable my_ops

  

有没有办法在viml中执行此操作。即: - 定义可以访问父范围的闭包函数?

感谢。

1 个答案:

答案 0 :(得分:5)

你可以在vimscript中使用类似闭包的东西。他们被称为字典功能。这些是与字典相关联的函数,就像它们的隐式上下文一样。在这些函数中,隐式上下文可以通过关键字self加入。所以,它们就像对象方法一样。有关更好的解释,请参阅here

使用它们,您可以像这样对样本进行编码,例如:

function! NewListener(method, opts) 
  let context = {'name': a:method, 'opts': a:opts}

  function! context.f(...)
    echo "running " . self.name . "\n"
    echo self.opts
    echo "\n"
  endfunction

  return context
endfunction

let listener = NewListener('foo', { 'a': 1, 'b': 2 })
call listener.f(1, 2, 3)