# Lua for Programmers Part 3: More Advanced Concepts

Posted on:September 7, 2012

If you haven’t read part one and two already, I’d highly recommend doing so. For reference, here’s a list of the parts in this series:

• Part 1: Language Essentials, covers fundamental syntax and concepts such as operators, loops, and functions.
• Part 2: Data and Standard Libraries, covers Lua’s built-in data types and some of the standard libraries.
• Part 4: Tips and Tricks, a collection of small things that you may find useful.

## Blocks and Scope

In part one I stated that Lua has “braces of a sort in the form of keywords like `then` and `do`.” Much like a language with C-based syntax, these “braces” represent blocks, which are essentially sequences of statements. An example of some blocks in Lua:

``````if x then
stuff()
moreStuff()
end

for i = 1, 10 do
local x = "foo"
end

function foo(x, y)
-- ...
end

-- explicit block
do
local x = 3
local y = 4
end``````

Conditionals, loops, and functions are all blocks. You can explicitly define a block as shown by the last example.

Lua uses lexical scoping, which means that every block has its own scope:

``````x = 5 -- global

function foo()
local x = 6
print(x) -- 6

if x == 6 then
local x = 7
y = 10 -- global
print(x) -- 7
end

print(x, y) -- 6, 10

do
x = 3
print(x) -- 3
end

print(x) -- 3
end

foo()
print(x, y) -- 5, 10``````

This example demonstrates the effect of variable shadowing. It also demonstrates how global variables can be defined at any scope if the `local` keyword is absent and no local variables exist by that name (as is the case with `y`).

### Collapsing Blocks

Lua allows you to collapse blocks onto one line:

``````function foo(x) return x * 5 end
if x then print(x) end
do foo() end``````

You’ll see this used a lot in Lua code.

## More On Functions

### Default Arguments

As mentioned in part one, Lua doesn’t directly support default arguments, but there are ways of getting the same behaviour. If a value isn’t supplied for a function argument it will default to `nil`, as all undefined variables do. Therefore:

``````function func(x, y, z)
if not y then y = 0 end
if not z then z = 1 end
-- code
end``````

A more common method is to use the `or` operator instead:

``````function func(x, y, z)
y = y or 0
z = z or 1
end``````

### Table Syntax

There’s an interesting syntax for calling functions that take a table as their only argument:

``````function foo(t)
return t[1] * t.x + t[2] * t.y
end

foo{3, 4, x = 5, y = 6} -- 39``````

That function call is equivalent to:

``foo({ 3, 4, x = 5, y = 6 })``

### Variable Arguments

Functions support the capturing of a varying number of arguments:

``````function sum(...)
local ret = 0
for i, v in ipairs{...} do ret = ret + v end
return ret
end

sum(3, 4, 5, 6) -- 18``````

To do so, just put `...` at the end of your argument list. You can access members of the list of arguments by putting them in a table (`{...}`) or through the `select` function:

``````function sum(...)
local ret = 0
for i = 1, select("#", ...) do ret = ret + select(i, ...) end
return ret
end``````

To put it briefly, `select` returns all values after the specified index, or the length of the list if `"#"` is provided instead. See the documentation for more.

Finally, just to be clear, `...` isn’t a data structure of any kind, it’s merely a list of values, like what you get from functions returning multiple values.

### `self`

Lua gives us a neat piece of syntactic sugar for calling and defining functions. When you have a function inside a table, you can do stuff like this:

``````t = {}

function t:func(x, y)
self.x = x
self.y = y
end

t:func(1, 1)
print(t.x) -- 1``````

The definition and call translate to:

``````function t.func(self, x, y)
self.x = x
self.y = y
end

t.func(t, 1, 1)``````

Although this is unnecessary in the example above, it becomes incredibly useful when mixed with metatables to implement things like object-oriented programming.

An important part of any language is how code is separated into multiple files. As you may know, Lua files generally end with the `.lua` extension. There are a few ways to load and run a file from inside a Lua script. Two of those ways are `dofile` and `loadfile`:

``````dofile("test.lua")

func()``````

All of those methods are essentially equivalent. Lua files are loaded as functions; this explains why `loadfile` returns a function. In addition to doing the job of `loadfile`, `dofile` also calls the function (if no errors occurred when compiling the file).

This method of loading files as functions opens up some interesting possibilities:

``````local message = "Cheese for everyone!"
local t = { 1, 2, 3, 4, 5 }
print(message)
return t``````

As you can see, files can return values and define local variables. Here’s how we might go about loading such a file:

``x = dofile("cheese.lua")``

`x` would be set to `t`, and the message from `cheese.lua` would be printed to the console.

### Package System

A much better and more common way to load files is via the package system:

``````require("cheese")
require("folder.subfolder.file")``````

The `require` function takes a path to a Lua file and searches for it in a number of ways. The manual explains the whole process, so I’ll just tell you what you need to know. `require` replaces each dot with the directory separator (”/” on Unix systems). It then looks for this file in the locations specified by `package.path`, which includes the current directory.

Once the file’s been loaded, `require` adds the path you specified to the `package.loaded` table. `require` won’t load any path found in this table, ensuring that files will only be loaded once.

That’s the essence of the package system, but there’s a lot more to it, so be sure to check out the documentation.

### Executing Strings

If you want to compile a string as a function within a Lua script, `loadstring` does the job:

``loadstring("print('hello')")()``

It works the same way as `loadfile`. This means that you can have local variables and return values inside the strings too.

## Metatables

Metatables are a very powerful and flexible feature of Lua that allow you to modify how tables behave. With them you can implement object-oriented programming, advanced data structures, and a lot more. Since I’ve already written a rather comprehensive tutorial on the subject, I’ll direct you to that instead of explaining metatables here. Another source you could read is, of course, Programming in Lua.

## Conclusion

As with the last part, there are many things I didn’t cover that you might want to check out yourself; some examples are iterators, coroutines, and error handling. Be sure to check out the final part of the series too.

As always, if you have any feedback, I’d love to hear from you.