# Litt's Lua Laboratory:Lua Variables (With Snippets)

Copyright (C) 2011 by Steve Litt

Debug like a Ninja

# Introduction

Lua variables come in the following types:
• Numbers
• Strings
• nil  (no value, nothing assigned)
• Booleans (true or false)
• Tables
• Functions
• Userdata  (data from a linked program from a different language)
We won't discuss the last two -- that's beyond the scope of this page.

Any time you want to get the type of a variable, use the type() function, which returns the type as a lower case string. For instance:
`var = "hello"print(type(var))`
The preceding would print the word "string".

# Numbers

Lua doesn't distinguish between short and long, signed or unsigned, int or float. They're all type number, and they can all be added, subtracted, multiplied and divided. Lua also converts strings to numbers if the string is such that it can represent a number and it's used in an arithmetic operation. Likewise, Lua converts a number to a string if the number is used in a string operation such as the .. concatenation operator.
`#!/usr/bin/lua a = 1            -- this is a numberb = 10           -- this is a numberc = "100"        --[[ this is a string representation                        of a number ]]print ("\nNumber below...")print(a)print(type(a))print ("\nNumber below...")print(b)print(type(b))print ("\nString below...")print(c)print(type(c))print ("\nNumber + number below...")print(a+b)print(type(a+b))print ("\nNumber + string below...")print(b+c)print(type(b+c))print ("\nNumber concatted to string below...")print(b..c)print(type(a..c))`
The preceding prints out the following, which pretty much proves all that's been said in this section:
`slitt@mydesk:~\$ ./test.luaNumber below...1numberNumber below...10numberString below...100stringNumber + number below...11numberNumber + string below...110numberNumber concatted to string below...10100stringslitt@mydesk:~\$`

# Strings

The following are strings:
`first="Steve"               -- string, value "Steve"last="Litt"                 -- string, value "Litt"whole=first .. last         -- string, value "SteveLitt"whole=first .. " " .. last  -- string, value "Steve Litt"`
In the Numbers section you learned that the concatination operator is .. and that Lua converts "3004" to a number if it's used in a numeric expression. There's a function called tostring() that converts its argument to a string. This is useful in print statements when you're not sure whether something will be a string or nil. Therefore it's especially useful in diagnostic prints.

Another way you can create a string is to use string.format(), which, as you can see, is a part of the string library. It's a lot like C's sprintf(). For instance here's code to format a string and a number that happens to be fractional into a string:
`#!/usr/bin/lua price_earnings_ratio = 15.521825348912company = "Troubleshooters.Com"mystring = string.format("The price to earnings ratio of %s is %f.",	company, price_earnings_ratio)print(mystring)mystring = string.format("The price to earnings ratio of %s is %.2f.",	company, price_earnings_ratio)print(mystring)mystring = string.format("The price to earnings ratio of %s is %8.2f.",	company, price_earnings_ratio)print(mystring)mystring = string.format("The price to earnings ratio of %s is %08.2f.",	company, price_earnings_ratio)print(mystring)mystring = string.format("The price to earnings ratio of %s is %03.2f.",	company, price_earnings_ratio)print(mystring)`
The preceding code produces the following output:
`slitt@mydesk:~\$ ./test.luaThe price to earnings ratio of Troubleshooters.Com is 15.521825.The price to earnings ratio of Troubleshooters.Com is 15.52.The price to earnings ratio of Troubleshooters.Com is    15.52.The price to earnings ratio of Troubleshooters.Com is 00015.52.The price to earnings ratio of Troubleshooters.Com is 15.52.slitt@mydesk:~\$`
You can see that the number you put between the % and the f controls the formatting of the number (or string or anything else). For instance, 8.2 means use two places after the decimal point, but have the whole number take up exactly 8 spaces including the decimal point. The last example in the preceding code shows that if doing so would cut significant digits off the whole part of the number, then it print the number using more than 8 spaces. Here's a brief and incomplete list of substitution characters:
 %s string %e or %E Scientific notation %d integer (signed decimal) %o octal (signed) %f floating point %u unsigned decimal %c character (use the ascii value) %x or %X unsigned hex

You have the string library available, including:
• string.upper() converts its string argument entirely to upper case
• string.lower() converts its string argument entirely to lower case
• string.len() delivers the length of the string. So does #stringname.
• string.sub() returns substrings based on starting position and ending position. Discussed later on this page.
• string.match() matches substrings in a string, including wildcards. Discussed on the Lua Regex page.
• string.find() finds substrings in a string, including wildcards. Discussed on the Lua Regex page.
• string.gsub() performs most of the functionalities of Perl's regular expressions.

## string.sub(strng, startpos, endpos)

This is the substring command. If endpos isn't given, the returned string goes to the end of the original string. Negative numbers start from the end instead of the beginning. The following program and its output make it pretty clear:
`mystring="123456789"print(string.sub(mystring, 1, 3))  -- print 1st 3 charactersprint(string.sub(mystring, -3))    -- print last 3 charactersprint(string.sub(mystring, 2))     -- eliminate first characterprint(string.sub(mystring, 4, -4)) -- eliminate the first 3 and last 3 chars`
Output looks as expected:
`slitt@mydesk:~\$ ./test.lua12378923456789456slitt@mydesk:~\$`
Remember, you use string.sub() to get substrings by position. To get them with matching, you use string.match(), string.find(), or string.gsub(). string.gsub() actually changes strings, and can transfer found strings to the replace string just like in Perl.

The string library has more functions than these. Take a look in the Lua docuementation. And remember to look at this subsite's Lua Regex page.

# nil

Nil is the absense of value. It means nothing has been assigned to a variable, or else the variable has deliberately been assigned nil. See this:
`local string1        -- Declare it local but don't assign. It's nillocal string2 = "hi" -- Not nilstring2 = nil        -- It's as if nothing had ever been assigned to it`
You might wonder why you'd ever want to assign nil to a variable.
• To give it to the garbage collector
• To make sure that variable cannot be used to change the table that had been assigned to it
Lua tables are groups of key/value pairs. Any key never specifically assigned a value will have a value of nil. So will a key specifically assigned a "value" of nil. There is no difference between these two. No table iterator will ever find keys with nil "values", whether those values were placed there or just never got assigned.

There are exactly two Lua entities that test as false: The boolean false and nil. Unlike C, 0 tests as true, not false. Because nil tests as false, you can do things like this:
`if not myvar	print("ERROR: myvar is nil, aborting!")	os.exit(1)end`
Or this:
`assert(myvar, "ERROR: myvar is nil, aborting!")`
Or you can use short circuit logic available in C, Perl and many other languages:
`print(string.format("Myvar=>%s<",myvar or "nil value"))`
The more generic way to do the preceding is this:
`print(string.format("Myvar=>%s<",tostring(myvar)))`
The preceding is better because if myvar happened to be a number or boolean it would print the number or either true or false. If myvar were a table it would print the table address, and if it were a function it would print the function address. In other words, it would not abort, which is often what you want, especially in debugging.

# Booleans

A variable becomes a boolean when you assign it either true, false, or the return of a function that returns a boolean, or a conditional. Examples follow:
`myvar = true         -- myvar is truemyvar = false        -- myvar is falsemyvar = 2 < 3        -- myvar is truemyvar = 2 > 3        -- myvar is false`
You test a boolean by simply naming the variable. For instance, let's say you have a boolean called should_continue. You could decide whether to skip over code in a loop as shown in the following pseudocode:
`should_continue = truewhile should_continue do    whatever()    if should_continue then        do_work_done_only_when_not_done()        should_continue = determine_whether_to_continue()    endend`
You can put together booleans with and, or and the like:
`if should_continue and found    whatever()endif found or first_time    whichever()end`
Remember, only boolean false and nil test false -- everything else tests true.

# Tables

First let me say this. 50% to 90% of Lua data involves tables, so it's a big, big subject covered much more extensively on this subsite's Lua Tables page.

Here's how you make an empty table:
```mytable = {"one", "two", "three"}        -- integer indexed keys starting at 1
mytable = {s="Sam, a="Al", d2="Don"}     -- Indexed by random strings
-- But not numbers
mytable = {}                             -- Empty table```
You set or add table key/value elements like this:
`mytable[numbervar] = value       -- Key is a numbermytable["stringvar"] = value     -- Key is a stringmytable.stringvar = value        -- Exactly the same as above`
You can also add with table.insert(), which has a two and three argument variety:

table.insert(mytable, newelement)       -- Inserts new element at the "end"
table.insert(mytable, pos, newelement)  -- Inserts the new element at position pos,
--   pushing everything else up
Did you notice I quoted the word "end" in the comment? Lua tables are not guaranteed to come out sorted by key, or sorted by the order they went in, or by anything else. There's no universally reliable way to find the "end" of a table, nor a universally reliable way to find out how many elements it has, without resorting to iterating the whole table.

 CAUTION! Do not rely on things like table.maxn(), #tablename and the like for getting a table's number of elements or its "end". Don't assume a table is sorted. table.maxn() and #tablename work only if you make sure all entries have integer keys and the keys start at 1 and end at, let's say 20, and there are no nil values between 1 and 20. If that's too much to assume, and it probably is, then don't assume it. This is not a problem because Lua gives you many ways to iterate all elements of a table, so there's little reason you need the highest numerical value. And even if you do, there are ways an application programmer can handle that. This will be discussed more on the Lua Tables page of this subsite, but I just want to say here this is not much of a limitation at all, as long as you make no assumptions.

# Functions

Try this:
`#!/usr/bin/lua hello = function() print("Hello World") endhello()`
As you can guess, it prints out "Hello World". Look what happened. We made a function with no name, and assigned it to a variable called hello. A function is just another piece of data you can assign all over the place. Watch this:
`#!/usr/bin/lua hello = function() print("Hello World") end  -- assign a function to hellohello()                                      -- execute that functiongoodbye = "See ya later"                     -- goodbye is a stringprint(goodbye)                               -- print the stringgoodbye = hello                              -- assign the hello function to goodbye goodbye()                                    -- run the new goodbye as a function`
Here's the result:
`slitt@mydesk:~\$ ./test.luaHello WorldSee ya laterHello Worldslitt@mydesk:~\$`
A function is just a piece of data. This is SUCH a powerful feature, making complex tasks simple. You can pass functions as arguments to functions, pass them back as return values, assign them to variables, and use them as elements of tables. Consider the following:
`#!/usr/bin/lua mypoint={x=3, y=9, show=function(tab) print(string.format("x=%d,y=%d",tab.x,tab.y)) end}mypoint.show(mypoint)`
Results:
`slitt@mydesk:~\$ ./test.luax=3,y=9slitt@mydesk:~\$`
What happened there? You created table mypoint with three keys: x, y and show. The show key was assigned a value that was a function. Hey, that's fair, functions are data. If the above is too ugly for you, do this:
`#!/usr/bin/lua mypoint={x=3, y=9}mypoint.show=function(tab) print(string.format("x=%d,y=%d",tab.x,tab.y)) endmypoint.show(mypoint)`
Same thing, except now you're creating the show key after the fact, not during the declaration of mypoint. Consider what you'd have if you added mypoint.setx, mypoint.sety, mypoint.getx, and mypoint.gety. Data and functions all wrapped into one. Wouldn't that be kind of like an object? That would be the most primative OOP like idiom available in Lua, but Lua can get A LOT more OOP than that. See the Lua OOP page of this subsite.

Now let me show you some Lua syntactic sugar. Syntactic sugar is when a language puts in an easier way to write the same thing. Remember this:
`mypoint.show(mypoint)`
Is it just me, or is that redundant and kind of stupid? No problem, you can use Lua syntactic sugar and change the dot to a colon, and then remove the redundant mypoint argument:
`mypoint.show(mypoint)       -- Shows x and y mypoint:show()              -- Does EXACTLY the same thing the same way`
So in other words, objectname.methodname(objectname) is the same as objectname:methodname().

Now be a little careful, because later you'll see that sometimes objectname isn't needed as an argument, in which case objectname.methodname() is the correct syntax.

By the way, in the preceding discussion, if you don't like me using OOP terms (technically Lua doesn't have OOP, but you can do all the same things with Lua as with "OOP" languages):

So in other words, tablename.functionname(tablename) is the same as tablename:functionname().

And sometimes, if the function doesn't require the argument of the table it's in, you do it like this:
`tablename.functionname()`

 NOTE Lua purists will flame me to death over saying Lua has OOP, because technically that's not true -- it has tables with functions inside of them. And it has metatables to implement something just like OOP inheritance and something very similar to polymorphism and even operator overloading. But don't call it OOP :-)

One more piece of syntactic sugar. You know all the times I've written:
`functname = function(args) do_something() end`
I could have written that more simply like this:
`function functname(args) do_something() end`
Or, in the case of a function in a table (or object :-))
`function tablename.functname(args) do_anotherthing() end`
Also, the syntactic sugar version works correctly during recursion, which the other version doesn't do automatically. The reason I introduced the other version first was to demonstrate that functions are just data.

All but the smallest functions are written on multiple lines. Thus you might write:
`function whichbigger(num1, num2)   local rtrn   if num1 > num2 then      rtrn = 1   elseif num1 < num2 then      rtrn = -1   elseif num1 == num2 then      rtrn = 0   else                      --internal error condition      print("FATAL internal error: neither bigger, smaller or same")      os.exit(1)end`
Arguments to functions are treated like local variables visible only inside the function but be careful, tables are passed by reference so any changes to table arguments inside the function affect the table outside the function. If you want a variable local to the function, add the word "local" as seen on the second line of the preceding function. Local variables are local to their enclosing block, which could be a loop, if statement, or even a small block deliberately made with do and end to make a tiny scope.

This section has barely scratched the surface. You haven't yet learned about closures, object makers, iterator makers, simulation of classes, or anything. These subjects are all detailed in the Lua Functions page and the Lua OOP page of this subsite.

But before learning the details of functions, there are several other things you need to learn.

# Local and Global Variables

Global variables are usually the kiss of death in any language. Any code anywhere can have its way with them, and there's no reasonable way to track down what code made what change. You know, maybe config options used by almost every subroutine and object should be global, but just about everything else should be local.

Unfortunately (in my opinion), Lua variables are global by default. To make them local you need to add the local keyword when declaring them:
`local age = 99local heightheight = "7 feet, 7 inches"`
You can declare a local with or without an initializer. If without, its value is nil. To find the scope of a local, go down from the local's declaration until you find the first end , elseif or until keyword. The local goes out of scope there. local's scope. Then go back up to the keyword matched by the end, elseif or until keyword. That will probably be a then, do, or elseif. Note that you might think of it as an if or while, but those conditionals are terminated by then and do respectively, and the code they run is terminated by an end, elseif or until.

Make all numbers, strings, booleans, table instances and "object" instances local unless you have a darned good reason to do otherwise.