Vimscript catch子句中的可变插值

时间:2013-09-13 23:27:17

标签: exception exception-handling vim

我正在为vim插件开发一个小的测试框架,我正在尝试实现一个调用用户指定函数的函数,并检查函数是否在需要时调用异常。我遇到的问题是我无法获得vim catch子句来接受传入测试函数的字符串。

这是我想要的简化版本。

function! TestException(fx, arguments, exception)
    let Fx = function(a:fx)
    try
        call call(Fx, a:arguments)
    catch a:exception           " Here's the problem line
        return 1
    endtry
    return 0
endfunction

如果我将异常硬编码到catch子句中,则此函数可以正常工作

catch /E740/
或者其他什么,但它不会插入传入的变量。我尝试在'execute'字符串中执行整个块,但这似乎也不起作用。

到目前为止,我已经提出了这个问题并且只是允许它捕获任何异常并且信任调用者来理解这种一般测试的局限性。

那么,有没有人知道如何解决这个问题,或者,有没有人知道如何找出它被捕获后抛出的异常,以便我可以将其与事后的参数进行比较?

2 个答案:

答案 0 :(得分:2)

为什么要使用match()?有=~#运营商。另请注意

  1. a:exception不应只是E470:它可能会被用户抛出。它应该是^Vim\%((\a\+)\)\=:E470(正则表达式取自:h :catch)。
  2. 您不能:throw Vim(call):E107: Missing parenthesis: abc:execute在这种情况下真的更好:

    function TestException(fx, arguments, exception)
        let d={}
        " XXX You must not ever use plain variables for holding
        "     function references because for every possible
        "     variable name it is possible to construct
        "         function Fx()
        "         endfunction
        "     definition that will prevent you from using this 
        "     variable.
        let d.Fx=function(a:fx)
        " Also note that for call() there is exactly no need in
        " using function references, call() accepts function names
        " as well. Thus I construct function reference above just
        " to write the above comment, but use a:fx in call() call
        " below.
        execute "try"
           \."\n   call call(a:fx, a:arguments, {})"
           \."\n   let r=0"
           \."\n catch /".a:exception."/"
           \."\n   let r=1"
           \."\n endtry"
        return r
    endfunction
    
  3. 注意上面的功能参考。如果您有Fx函数,那么会发生什么{。{1}}。
  4. 请注意上面的E705: Variable name conflicts with existing function: Fx个参数。如果您删除call()来电,您也可以传递function()函数功能参考。如果你添加第三个参数(一些字典,我通常使用空;这些函数可能会或可能不会实际使用TestException变量,但无论如何需要第三个参数)这也将允许匿名函数,而不会有任何区别非匿名非字典函数调用。
  5. 请注意selfreturn r:我猜这是您在创建解决方法时发现的错误(如果我将此块包装起来保持返回我总是为零)。如果我将let r=…替换为let r=…,也会有效(请注意,return …将位于return 0块内,而不是在:try块之外),但单个退出点看起来更好。< / LI>

答案 1 :(得分:0)

吉姆斯图尔特,这是完美的解决方法。我现在有类似

的东西

function! TestException(fx, arguments, exception)
    let Fx = function(a:fx)
    try
        call call(Fx, a:arguments)
    catch
        if match(v:exception, a:exception) >= 0
             return 1
        else
             throw v:exception
        endif
    endtry
    return 0
endfunction

Vim不喜欢手动抛出Vim异常,但它仍然让用户知道何时抛出了另一个异常而不是预期的异常。不敢相信我没注意到v:异常。