Hi,

And part #3:

Let's consider the following code in file foo.vim:

function! s:Foo() dict
    echo self.data
endf

let g:foo = {'data': 'bar', 'Foo': function('s:Foo')}

Now, when I type:

:source foo.vim
:echo g:foo.Foo()

I get the following error:
E120: Using <SID> not in a script context: s:Foo
E15: Invalid expression: g:foo.Foo()

When I place this in a file bar.vim and do :so bar.vim, I get:
E117: Unknown function: s:Foo
E15: Invalid expression: g:foo.Foo()

From the help text on function()

function({name})                                        *function()* *E700*
                Return a |Funcref| variable that refers to function {name}.
                {name} can be a user defined function or an internal function.

I concluded that this function would do more that just storing the functions name as string. Based on my example, it seems I was wrong. Not being able to refer to script local functions, IMHO makes function() rather pointless, I'd say.

One can work around the problem by using the trick described in :help <SID> though.

I also noticed some inconsistency with respect to whether funcrefs can only be assigned to variables beginning with an upper-case letter.

Vim doesn't complain about

let g:foo = {'data': 'bar', 'foo': function('s:Foo')}
call g:foo.foo()

but it throws E704 when doing:

let ffoo = function('s:Foo')

From my experience with this, I'd say that this is too restrictive as, e.g., call() also accepts a string. So a code like the following is basically correct but won't be accepted by vimscript:

fun! Example(arg)
    echo a:arg
endf

fun! Caller(fn, args)
    let afn = a:fn
    return call(afn, a:args)
endf

call Caller(function('Example'), [1])
call Caller('Example', [1])

Regards,
Thomas.


Reply via email to