Я надеюсь вызвать «статическую» словарную функцию с помощью 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 для словаря, но переменная "self" тогда недоступна.
Таким образом, логика, по-видимому, указывает на то, что если «self» недоступно, то должна быть возможность вызывать функцию, на которую ссылается Funcref, без словаря. Однако, похоже, это не так. Я что-то упустил?
Информация о версии Vim:
$ aptitude show vim-gnome
Package: vim-gnome
State: installed
Automatically installed: no
Version: 2:7.2.245-2ubuntu2
Редактировать
Что я действительно хочу сделать, так это разрешить функциям словаря прозрачно выполнять вызовы либо к другим функциям словаря, либо к функциям вне словаря.
Это возможно, передав self в качестве третьего параметра в вызове call () (спасибо @ZyX); этот параметр просто игнорируется, если вызывается не словарная функция. Я нахожу это удивительным, потому что он сильно отличается от того, как работают объектно-ориентированные конструкции в других языках. Но я думаю, что ООП в vimscript во многих отношениях больше похож на С, чем на С ++.
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
, то это будет работать достаточно хорошо.
Это означает, что помимо возможности создания структур наследования с использованием клонированных и измененных словарей (например, копирование прототипов), некоторые методы могут быть ссылками на не словарные функции.