This pattern will let you assign meaningful names to each argument, and provide a default value for any arguments that were not provided:
function FunctionName(foo, ...)
let bar = a:0 >= 1 ? a:1 : 0
let baz = a:0 >= 2 ? a:2 : 0
...
" Code that makes use of a:foo, bar and baz
As pointed out by Boris Brodski:
a:0
counts the number of optional arguments passed
a:1
, a:2
, ... let us access the optional arguments
The mandatory arguments (just foo
in the example above) are not counted
condition ? result_if_true : result_if_false
is the conditional (ternary) expression, which evaluates to the second or third term depending on whether the first term was true or not.
So if no third argument is provided, baz
will take the default value of 0
.
One concern with the above example is that a:foo
can only be accessed with the a:
prefix, whilst bar
and baz
can do without a prefix. Since this is not very consistent, you may prefer to pull out all of the arguments into local variables, like so:
function FunctionName(...)
let foo = a:1 " Will throw an error if no arg was provided
let bar = a:0 >= 2 ? a:2 : 0
let baz = a:0 >= 3 ? a:3 : 0
...
" Code that makes use of foo, bar and baz
(Technically, you can use the l:
prefix to refer to local variables inside a function, for example l:baz
, but this is redundant so I would not recommend it.)
But I do recommend that you use this form whenever possible:
function! s:FunctionName(...)
The !
allows you to redefine your function at runtime (e.g. by reloading the script), and the s:
limits the function to script scope. That avoids polluting the global namespace (and risking collision) if your function is only referenced from elsewhere inside the script. It is generally the preferred way to define functions when they do not need to be globally visible. ;-)