# Lua Design Patterns  wiki

This page is intended for Lua design patterns. See [Wikipedia: design pattern] for background.

### Pattern: Global Collector

Traditionally, if we want a define a table of variables, or key-value pairs, we use table construction syntax ` {...} `:

```-- traditional method.
local squares = {}; for n=1,10 do squares[n] = n^2 end
local v = {
x = 50,
squares = squares,
hello = function() print("hello?") end
}
```

However, by appropriate definition of a function `collect`, we may alternately construct as follows:

```local v = collect(function()
if true then x = 50 end
squares = {}; for n=1,10 do squares[n] = n^2 end
function hello() return "hello?" end
end)
```

Note one potential benefit is that statements of code can be interspersed with and build the key-value definitions. It does impose a bit more overhead though.

`collect` is defined as follows:

```function collect(f)
-- This collects globals defined in the given function.
local collector = setmetatable({}, {__index = _G})
-- Call function in collector environment
setfenv(f, collector)()
-- Extract collected variables.
local result = {}; for k,v in pairs(collector) do result[k] = v end
return result
end
```

Test suite:

```assert(v.x == 50)
assert(#v.squares == 10)
assert(v.hello() == "hello?")
assert(v.print == nil) -- ensure _G not included.
print("done")
```

This type of mechanism is used in the Lua 5.1 module system, where the collecting function is given in a file and the `require`/`module` functions implement the collect mechanism (as well as other things). See Chapter 15 of [Programming in Lua 2nd Edition].

```module("mymodule")
x = 50
color = "blue"
function hello() return "hello?" end
```

--DavidManura, 2006-10, Lua 5.1

### Pattern: Function chains / hooks

There are a bunch of interesting ways to execute a series of actions on a given event. One way that I've seen that was somewhat less than efficient looked like this:

```for _,v in pairs(files_in_directory) do
dofile(v)
if action then
action(args)
end
action = nil
end
```
where a file in the directory might look like this:
```function action(something)
print(something)
end
```
This is inefficient; it requires everything to be reparsed each call, and it smashes the global called "action". It doen't provide for effective weighting, either. In naim, we use a hook system that's done in C that creates a bunch of chains, to which we can register C and Lua actions.

I wrote a system that allows one to create their own hook chains in Lua that can be executed like functions. The syntax seems fairly logical to me:

```require"hooks"
myhooks = {}
myhooks.test = hooks:new()
myhooks.ref1 = myhooks.test:insert(function (foo, bar) print("Test 1", foo, bar) end, 100)
myhooks.ref2 = myhooks.test:insert(function (foo, bar) print("Test 2", foo, bar) end, 50)
myhooks.ref3 = myhooks.test:insert(function (foo, bar) print("Test 3", foo, bar) end, 150)
print"--"
myhooks.test("Hello", "world")
myhooks.test:remove(myhooks.ref1)
print"--"
myhooks.test("Hello", "world")
```

Running this would produce output like:

```--
Test 2  Hello   World
Test 1  Hello   World
Test 3  Hello   World
--
Test 2  Hello   World
Test 3  Hello   World
```

The code that drives this is available at . Still to do: support for writable arguments. This is necessary in naim if one wishes to modify a string that gets passed through; i.e., a filter module might want to substitute all instances of "lol" to "<grin>" in the input string, and then pass the modified string through to further hooks in the chain. Patches thoughtfully accepted.

-- JoshuaWise, 2007-02-01

### Pattern: Static Local Variables

One sometimes runs into a conflict where a variable should be lexically scoped to a particular function but should also have a lifetime longer than the function call. In the below case, the `sounds` table is used only by the function `soundit`, which would suggest bringing it inside the `soundit` function, but it would be wasteful to reconstruct `sounds` on each function call, so often the programmer will keep `sounds` outside:

```local sounds = {
a = "ay",
b = "bee",
c = "see",
....
}
local function soundit(x)
assert(type(x) == "string")
return sounds[x]
end
```

In the C language, we might make `sounds` a static variable inside `soundit`. In Lua, the usual suggestion here, if one wants to limit the scope of `sounds`, is to surround `sounds` and `soundit` with a `do` block:

```local soundit; do
local sounds = {
a = "ay",
b = "bee",
c = "see",
....
}
function soundit(x)
assert(type(x) == "string")
return sounds[x]
end
end
-- note: sounds not visible outside the do-block.
```

One complaint is that now the implementation of the function is spread outside the function, the name `soundit` is duplicated, and the code is further indented/ugly, appearing less like a function definition. Furthermore, `sounds` will get initialized regardless whether `soundit` ever gets called (thereby imposing a load-time overhead). The following approach keeps `sounds` outside the function but moves its initialization inside the function. Due to the short-circuiting behavior of `or`, it will generally impose little additional overhead at call-time:

```  local soundit; do local sounds; function
soundit(x)
sounds = sounds or {
a = "ay",
b = "bee",
c = "see",
....
}
assert(type(x) == "string")
return sounds[x]
end end
```

In fact, we may just give up perfection and let the lexical scope spill over for enhanced readability:

```local sounds

local function soundit(x)
sounds = sounds or {
a = "ay",
b = "bee",
c = "see",
....
}
assert(type(x) == "string")
return sounds[x]
end
```

Here are two variations involving the construction of closures. These are a bit more tidy than the `do` block approach but do impose the load-time overhead of at least constructing a temporary function.

```local soundit = (function()
local sounds = {
a = "ay",
b = "bee",
c = "see",
....
}
return function(x)
assert(type(x) == "string")
return sounds[x]
end
end)()
```

```local soundit = (function()
local sounds
return function(x)
sounds = sounds or {
a = "ay",
b = "bee",
c = "see",
....
}
assert(type(x) == "string")
return sounds[x]
end
end)()
```

--DavidManura, 2007-03

### Pattern: <Pattern Name>

<Pattern description> (Add more patterns here)