Sep 11
27
Tables, always tables… (Lua)
Lua is an interesting language, easy to learn but difficult to master. Difficult things can often be achieved with a few lines of code but as a drawback there is room for many potential errors that can get very difficult to solve, for example, here is a common pitfall:
myTable = {"element1","element2","element3"}
print( myTable [ 1 ] ) -- prints: element1
print( myTable [ 2 ] ) -- prints: element2
print( myTable [ 3 ] ) -- prints: element2
print( index ) -- index was declared previously somewhere, prints: 1
print( myTable [ index ] ) -- prints: nil woot? should print element1
After a first look to this piece of code I thought the problem was the scope of the variable index. If this was the case we should get nil when printing it but it was declared and assigned correctly and it was in scope too.
How can this be?
The answer is simple but hard to detect (especially after hours of long work) and has to do with the way tables are handled in Lua,: associative arrays.
The elements of a table can be indexed with numbers, but also with strings or any other type (except nil). To make this clear, let’s take a look to the following table declarations:
myTableA = { } -- elements indexed with numbers
myTableA[1] = "element1"
myTableA[2] = "element2"
myTableA[3] = "element3"
myTableB = { } -- elements indexed with strings
myTableB["1"] = "element1"
myTableB["2"] = "element2"
myTableB["3"] = "element3"
index = 3
print( myTableA [ index ] ) -- prints: element3
print( myTableB [ index ] ) -- prints: nil
index = "3"
print( myTableB [ index ] ) -- prints: element3
We have found the problem with the original code: when we print the value of index we see it’s 1 but since myTable is indexed with numbers by default, it’s clear that index is not a number and we can prove it:
print( type(index) ) -- prints: string A-HA!
Going back to the problematic code, we can solve it like this:
myTable = {"element1","element2","element3"} -- Indexed with numbers!
print( myTable [ 1 ] ) -- prints: element1
print( myTable [ 2 ] ) -- prints: element2
print( myTable [ 3 ] ) -- prints: element2
print( index ) -- prints: 1 (but it is still a string)
print( myTable [ tonumber ( index ) ] ) -- prints: element1
In this case (a real one), the variable index was being read form a file. We need to convert it to a number so myTable can find it’s match.
Thanks for reading!
Raúl Beltrán
