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

71011Re: Funcref and script local functions

Expand Messages
  • Hari Krishna Dara
    Jul 3, 2006
    • 0 Attachment
      On Mon, 3 Jul 2006 at 6:35am, Eric Arnold wrote:

      numbered functions.
      > I'm still not getting it, I think. Do you have a case where the
      > numbered function scheme will break down, or is it about the
      > callbacks, described below?

      I think it is best to leave the discussion about numbered functions. It
      hasn't got much value to the current discussion of whether the functions
      references to the script local functions should be callable outside the
      script in which the functions are defined.

      > > >
      > > >
      > > > On 6/29/06, Hari Krishna Dara <hari_vim@...> wrote:
      > > > >
      > > > > When Funcref's were introduced in Vim7, I expected them to work for
      > > > > script-local functions, across scripts. The documentation didn't say
      > > > > that, but it didn't say that it wouldn't either, and I thought that
      > > > > is one of its biggest uses (other than the actual intended
      > > > > functionality, which is for implementing numbered functions). However,
      > I'm not sure that there is a problem. As with C code, if you have
      > the option of declaring a function global/local, public/private, etc.
      > I think Vim script is allowing these options.
      > Are you saying that you want to override the private script
      > declarations by declaring a function reference to a low enough level
      > pointer that it goes under the scope checker?

      As Yakov Lerner already clarified, this should be allowed by Vim. As we
      already know, Vim's script-local scoping for functions is not realy
      intended to prevent external callers. In fact, Vim allows you to use
      these functions in all your mappings etc., and the calls then originate
      from outside outside the script context. This is probably why Vim allows
      a script local function be called in general, using the <SNR> syntax.
      All that I am saying is that this should be more formalized for
      Funcrefs (see below).

      > > > > found that the Funcref references for such functions can't actually be
      > > > > passed out to other scripts. This reduces the usefulness of this
      > > > > as we can't register private functions to receive callbacks from other
      > > > > scripts.
      > I think this is probably a request that it be more object oriented
      > than it is, ie. you really want object-scoped functions, not
      > script-scoped. You seem to want the script localized, so it can't be
      > access generally, but then be public for registering callbacks. This
      > seems like an object-scope problem.

      The script-local functions in Vim is more of a means to distinguish the
      public API from private. They are not really intended to prevent outside
      callers. We are not going to build a security system using Vim scripting
      after all.

      > I think that the numbered functions are allowed globally, probably
      > because they are intended to be used as you describe, for callbacks
      > from other scripts, since they are only created for the 'dict'
      > "object" functions, as far as I can tell.
      > > > >
      > > > > What is weird is that the the Funcref() actually behaves exactly like
      > > > > the function name itself. Say you have a function called s:T() and say
      > > > > the script id is 60. The Funcref obtained via function('s:T') can't be
      > > > > called from outside the script, but if the Funcref is obtained using
      > > > > function('<SNR>60_T'), then it will be fine. Also, a Funcref obtained
      > Both of these examples seem reasonable to me. If you declare a
      > function reference to a script-local object, s:T then you don't
      > want it being accessed outside the script. If you declare a
      > '<SNR>60_T' reference, then you probably wanted to use it outside
      > the script, otherwise you wouldn't have gone through the trouble of
      > finding the script id.

      You can't declare a function using the <SNR> prefix. When you use the s:
      or <SID> prefix, vim automatically changes it to the <SNR> form using
      the id of the script. When you want to register a callback, through an
      autocommand or a map, you don't need to go through the trouble (which
      actually is not a big trouble) of finding the script id, as Vim takes
      care of expand <SID> to the right value. This doesn't work the same,
      when you want to register the same function as a callback with another
      plugin, so you have to explicitly pass the function name with the <SNR>
      form (ie., <SNR>60_T not <SID>T). If Funcref's on s:T is same as
      <SNR>60_T, then this makes it simpler (and more formal) (again, see

      > > > > using these two methods will not be to the same object, though you
      > > > > expect them to be. The below echoes 0:
      > How did you test what the object was? Actually, I wouldn't expect it
      > to be the same object in any case, since each reference to it should
      > crease a new instance. They both might refer to the same function
      > definition stored internally, but I don't know.

      As my code sample below shows, the "is" operator on two separate
      references of "s:T" gives you "true", but if one reference is to the
      <SNR> form, you get "false". This is counter-intuitive, as you
      referencing the same exact function.

      > Also, we aren't talking about true "objects", just to be clear, but an
      > enhancment that allows object-oriented-like functional access. This
      > limits the expectations we can have.

      This limitation is not applicable to my argument.


      > >
      > > No, that is not what I was saying. If there is a way to declare
      > > variables without initializing them, I would have said something like:
      > >
      > > Funcref var
      > >
      > > However, the equivalent of the above is to say:
      > >
      > > let var = function('somefunc')
      > >
      > > The alternative is of course to just initialize the variable as and when
      > > it is required, but I generally don't like this approach, as it is not
      > > clear which variables are being used.
      > >
      > I want to have it auto-initialize whether in a "let" statement, or an
      > implicit setting via a function call argument. And I'd like to be
      > able to test a value that hasn't been explicitly initialized, i.e.
      > if var1[1].elem1 > 0
      > ...
      > where nothing about "var1" has been defined, but is used such that
      > automatic NULL elements would have to be created manually in any case.
      > If I really want it to fail if [1] or .elem1 are not
      > defined, I can use 'exists()' or 'has()'. As I said elsewhere, it
      > should be an option, for backward compatibility.

      I am not talking about "initialization" here, just declaration.


      Do You Yahoo!?
      Tired of spam? Yahoo! Mail has the best spam protection around
    • Show all 12 messages in this topic