vimscript: вызов [не] словарных функций с помощью call () внутри словарных функций - PullRequest
4 голосов
/ 01 апреля 2010

Я надеюсь вызвать «статическую» словарную функцию с помощью 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, то это будет работать достаточно хорошо.

Это означает, что помимо возможности создания структур наследования с использованием клонированных и измененных словарей (например, копирование прототипов), некоторые методы могут быть ссылками на не словарные функции.

1 Ответ

5 голосов
/ 01 апреля 2010

Для всех функций словаря требуется некоторый словарь, предоставленный в качестве третьего аргумента для call(). Все анонимные функции являются словарными функциями. Все функции, объявленные с использованием function dict.func(), являются анонимными. Просто укажите {} в качестве третьего аргумента для всех вызовов call() и забудьте об этом.

И перечитайте документацию. Self является доступным в вашей функции. Документация говорит, что вы не станете доступными, если вы сделаете это: let dict.func=function("Foo").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...