Tuesday, January 20, 2015

Re: why "function!" instead of just "function"



2015-01-20 13:48 GMT+03:00 John Beckett <johnb.beckett@gmail.com>:
Bao Niu wrote:
> I am learning Vimscript and I wonder if there is any
> difference between writing "function!" vs. "function"?

Expanding on Tim's reply, suppose you have file h.vim which
contains:

  function! Hello()
    echoerr 'Hello'
  endfunction

In Vim, assuming the directory shown by :pwd is the directory
holding h.vim, you can do the following to "source" the script:

  :so h.vim

That executes h.vim which defines the function.

You could edit h.vim and source it again, and the edited
function would replace the original.

The idea is to help you to not accidentally overwrite functions.
If you do not have "!", the function will not be replaced if you
try to define it again.

This idea is only useful for small scripts for one-time job. It is bad to use it *always* because you cannot rely on the results of resourcing: there are loads of "state" things that persist while they should not: `:function!` overwrites existing function, but it is helpless if you removed or renamed a function in a script and resource it to check whether you have done everything right. It also will silently spoil user configuration if user or some plugin he installed has chosen the same function name.

Thus I suggest to *never* write :function! in any file in any directory in &runtimepath, but this is OK for testing answers for stackoverflow or vim-use, creating a script for a one-time job or something like this where you know and control such leftovers or just do not care. If you really do need to reload plugin without restarting Vim you can use same solution frawor uses: almost all s: functions are put into s:F dictionary (actually, in any dictionary: you just need to have them anonymous) so everything is needed to delete s: functions is :unlet s:F. All functions that were not put into s:F dictionary should be listed in s:_functions so frawor can delete them for you when you unload plugin (so function definition looks like

    function Foo()
    endfunction
    let s:_functions += ['Foo']

). Then frawor receives reference to s: dictionary, so it is able to do anything with it (including deleting s:F by unletting `F` key and iterating over s:_functions). Since all functions are global you can also add s:Foo function to a list (specifically frawor is also notified about plugin SID, so it can replace s: with actual function prefix if needed).

But this reloading facility is rather complicated and if you are not basing on frawor for some other reason it is easier and more robust to just reload Vim and never use :function! or :command! in plugins.
 

John


--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments: