055027714e9b

Function arguments.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 13 Oct 2011 23:54:12 -0400
parents 93d00f94217a
children 4d919ca7401b
branches/tags (none)
files chapters/23.markdown chapters/24.markdown outline.org

Changes

--- a/chapters/23.markdown	Thu Oct 13 00:01:07 2011 -0400
+++ b/chapters/23.markdown	Thu Oct 13 23:54:12 2011 -0400
@@ -8,13 +8,13 @@
 
     :function meow()
 
-You might think this would start defining a functione named `Meow`.
+You might think this would start defining a function named `Meow`.
 Unfortunately this is not the case, and we've already run into one of
 Vimscript's quirks.
 
 **Vimscript functions *must* start with a capital letter if they are unscoped!**
 
-Even if you *do* add a scope to a function (we'll talk about that in a bit) you
+Even if you *do* add a scope to a function (we'll talk about that later) you
 may as well capitalize the first letter of function names anyway.  Most
 Vimscript coders seem to do it, so don't break the convention.
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chapters/24.markdown	Thu Oct 13 23:54:12 2011 -0400
@@ -0,0 +1,114 @@
+Function Arguments
+==================
+
+Vimscript functions can, of course, take arguments.  Run the following commands:
+
+    :function DisplayName(name)
+    :  echom "Hello!  My name is:"
+    :  echom a:name
+    :endfunction
+
+Run the function:
+
+    :call DisplayName("Your Name")
+
+Vim will display two lines: "Hello!  My name is:" and "Your Name".
+
+Notice the `a:` in the name of the variable that we passed to the `echom`
+command.  This represents a variable scope, which we talked about in an earlier
+chapter.
+
+Let's remove this scope prefix and see how Vim reacts.  Run the following
+commands:
+
+    :function UnscopedDisplayName(name)
+    :  echom "Hello!  My name is:"
+    :  echom name
+    :endfunction
+    :call UnscopedDisplayName("Your Name")
+
+This time Vim complains that it can't find the variable `name`.
+
+When you write a Vimscript function that takes arguments you *always* need to
+prefix those arguments with `a:` when you use them to tell Vim that they're in
+the argument scope.
+
+Varargs
+-------
+
+Vimscript functions can optionally take variable-length argument lists like
+Javascript and Python.  Run the following commands:
+
+    :function Varg(...)
+    :  echom a:0
+    :  echom a:1
+    :  echo a:000
+    :endfunction
+
+    :call Varg("a", "b")
+
+This function shows us several things, so let's look at each one individually.
+
+The `...` in the function definition tells Vim that this function can take any
+number of arguments.  This is like a `*args` argument in Python functions.
+
+The first line of the function echoes the message `a:0` and displays `2`.  When
+you define a function that takes a variable number of arguments in Vim, `a:0`
+will be set to the number of extra arguments you were given.  In this case we
+passed two arguments to `Varg` so Vim displayed "2".
+
+The second line echoes `a:1` which displays "a".  You can use `a:1`, `a:2`, etc
+to refer to each extra argument your function receives.  If we had used `a:2`
+Vim would have displayed "b".
+
+The third line is a bit trickier.  When a function has varargs, `a:000` will be
+set to a list containing all the extra arguments that were passed.  We haven't
+looked at lists quite yet, so don't worry about this too much.  You can't use
+`echom` with a list, which is why we used `echo` instead for that line.
+
+You can use varargs together with regular arguments too.  Run the following
+commands:
+
+    :function Varg2(foo, ...)
+    :  echom a:foo
+    :  echom a:0
+    :  echom a:1
+    :  echo a:000
+    :endfunction
+
+    :call Varg("a", "b", "c")
+
+We can see that Vim puts "a" into the named argument `a:foo`, and the rest are
+put into the list of varargs.
+
+Assignment
+----------
+
+Try running the following commands:
+
+    :function Assign(foo)
+    :  let a:foo = "Nope"
+    :  echom a:foo
+    :endfunction
+
+    :call Assign("test")
+
+Vim will throw an error, because you can't reassign argument variables.  Now run
+these commands:
+
+    :function AssignGood(foo)
+    :  let foo_tmp = a:foo
+    :  let foo_tmp = "Yep"
+    :  echom foo_tmp
+    :endfunction
+
+    :call AssignGood("test")
+
+This time the function works, and Vim displays "Yes".
+
+Exercises
+---------
+
+Read the first two paragraphs of `:help function-argument`.
+
+Read `:help local-variables`.
--- a/outline.org	Thu Oct 13 00:01:07 2011 -0400
+++ b/outline.org	Thu Oct 13 23:54:12 2011 -0400
@@ -23,9 +23,7 @@
 ** DONE conditionals
 ** DONE comparisons
 ** DONE functions
-** TODO function scoping
-** TODO function varargs
-** TODO functions (more)
+** DONE function arguments
 ** TODO strings
 ** TODO string functions
 ** TODO normal!
@@ -36,6 +34,7 @@
 ** TODO dictionaries
 ** TODO paths
 ** TODO exceptions
+** TODO functions again
 ** TODO command!
 * part 3 - creating a full plugin
 ** TODO intro and plugin layout