vimscript:在字典函数中使用call()调用[non]字典函数

时间:2010-04-01 02:39:55

标签: oop vim

我希望使用call()调用“静态”字典函数。 “静态”是指关键字“dict”未在函数定义中使用。我使用这个命名法,希望这个关键字的作用是在java / C ++ / etc中声明一个静态成员函数,即将函数名放在类名称空间中,但允许在不引用对象的情况下调用它

然而,这似乎不起作用。例如:

" Setup:
let testdict = { }
funct! testdict.funct() 
  echo "called" 
endfunct

" Tests:
"   Following each line is an indented comment
"     containing its output in message land, ie what was echoed.
call testdict.funct()
  " called
echo testdict.funct
  " 667
echo string(testdict.funct)
  " function('667')
echo function('667')
  " E475: Invalid argument: 667
echo function('testdict.funct')
  " testdict.funct
call call(testdict.funct, [ ])
  " E725: Calling dict function without Dictionary: 667

" Same deal if there's an intermediate variable involved.
let TestdictDotFunct = testdict.funct
echo TestdictDotFunct
  " 667
echo string(TestdictDotFunct)
  " function('667')
call TestdictDotFunct()
  " E725: Calling dict function without Dictionary: 667

从帮助主题 E725

  

也可以添加一个没有“dict”属性的函数作为   Funcref to a Dictionary,但“self”变量不可用。

所以逻辑似乎表明如果“self”不可用,那么应该可以在没有Dictionary的情况下调用Funcref引用的函数。然而,情况似乎并非如此。我错过了什么吗?

Vim版本信息:

$ aptitude show vim-gnome
Package: vim-gnome
State: installed
Automatically installed: no
Version: 2:7.2.245-2ubuntu2

修改

想要做的是允许字典函数透明地调用其他字典函数或非字典函数。

这可以通过将 self 作为call()调用中的第三个参数传递(感谢@ZyX);如果正在调用非字典函数,则忽略此参数。我发现这种情况令人惊讶,因为它与其他语言中面向对象的结构的工作方式非常不同。但是我觉得vimscript的OOP在很多方面比C ++更像是C语言。

EG

let dict = { }
funct! dict.func(arg)
  echo 'dict.func called.'
  echo 'argument: '.a:arg
endfunct
funct! dict.callfunc_passself(arg)
  call call(self.func, [a:arg], self)
endfunct
funct! dict.callfunc_nopassself(arg)
  call call(self.func, [a:arg])
endfunct

funct! Func(arg)
  echo "Func called."
  echo 'argument: '.a:arg
endfunct


call dict.callfunc_passself('argument supplied to dict.callfunc')
  " dict.func called.
  " argument: argument supplied to dict.callfunc
call dict.callfunc_nopassself('argument supplied to dict.callfunc')
  " E725: Calling dict function without Dictionary: 37

let dict.func = function('Func')
call dict.callfunc_passself('argument supplied to dict.callfunc')
  " Func called.
  " argument: argument supplied to dict.callfunc
call dict.callfunc_nopassself('argument supplied to dict.callfunc')
  " Func called.
  " argument: argument supplied to dict.callfunc

因此,只要在字典函数中对[non]字典函数的调用将self作为第三个参数传递给call,那么这将非常有效。

这意味着除了能够使用克隆和修改的字典(即复制原型)构建​​继承结构之外,还可以让一些方法引用非字典函数。

1 个答案:

答案 0 :(得分:5)

所有字典函数都需要一些字典作为call()的第三个参数。所有匿名函数都是字典函数。使用function dict.func()声明的所有函数都是匿名的。只需提供{}作为所有call()次来电的第三个参数,然后忘记这一点。

重读文档。您的功能中可以使用 。文档说如果您执行此操作,则无法使用self:let dict.func=function("Foo")