Loading ...
Sorry, an error occurred while loading the content.

Re: Dictionary functions & function() & Funcrefs & & E120

Expand Messages
  • Bram Moolenaar
    ... It s very simple: script-local functions can only be used in the script where they are defined. If you want a dictionary-local function you should use
    Message 1 of 2 , Apr 29, 2007
    • 0 Attachment
      Thomas wrote:

      > 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.

      It's very simple: script-local functions can only be used in the script
      where they are defined. If you want a dictionary-local function you
      should use ":help numbered-function".

      > 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])

      It's a matter of name spaces. Inside a dictionary there is no conflict
      with Vim functions. In the global namespace Vim functions start with a
      lower case character, user functions with an upper case character.
      That's completely consistent.

      --
      I am also told that there is a logical proof out there somewhere
      that demonstrates that there is no task which duct tape cannot handle.
      -- Paul Brannan

      /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
      /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
      \\\ download, build and distribute -- http://www.A-A-P.org ///
      \\\ help me help AIDS victims -- http://ICCF-Holland.org ///
    Your message has been successfully submitted and would be delivered to recipients shortly.