Lua - Tables and Metatables
Lua provides an interesting option to modify the behavior of a table. For example, to get a default value in case key is not present in the table.
A metatable is another table which can modify the table behavior with the help of a key set and related meta methods. These meta methods are powerful Lua functionality that enables features like −
Changing/adding functionalities to operators on tables.
Looking up metatables when the key is not available in the table using __index in metatable.
There are two important methods that are used in handling metatables which includes −
setmetatable(table,metatable) − This method is used to set metatable for a table.
getmetatable(table) − This method is used to get metatable of a table.
Syntax - Setting MetaTable
Let's first look at how to set one table as metatable of another. It is shown below.
mytable = {}
mymetatable = {}
setmetatable(mytable,mymetatable)
The above code can be represented in a single line as shown below.
mytable = setmetatable({},{})
Example - Using _index to get a default value in associated table
A simple example of metatable for looking up the meta table when it's not available in table is shown below.
main.lua
mapTable = {Mon="Monday", Tue="Tuesday", Wed="Wednesday"}
-- set the metatable
setmetatable(mapTable, {
-- self represent the table on which metatable is applied
-- index is the non-existing index
__index = function(self, index)
return "Not defined."
end
})
-- print value using existing key
print(mapTable.Mon)
-- print value using non-exiting key
print(mapTable.Sun)
Output
When we run the above program, we will get the following output−
Monday Not Defined
Let us explain what happened in the above example in steps.
The table mapTable here is {Mon="Monday", Tue="Tuesday", Wed="Wednesday"}.
Metatable is set for mytable that contains a function for __index, which we call as a metamethod.
The metamethod does a simple job of looking up for an index. If a non-existing index is passed to the table, then a default value of "Not defined." is returned, otherwise the corresponding value is printed.
Example - Using _index to get a default value in numerically indexed table
In case numerically index table as well, we can set and use metatable to change table behavior as shown below−
main.lua
numbers = { -1, -2, -3, -4, -5, -6}
-- set the metatable
setmetatable(numbers, {
-- self represent the table on which metatable is applied
-- index is the non-existing index
__index = function(self, index)
return math.random(10)
end
})
-- print value using existing key
print(numbers[1])
-- print value using non-exiting key
print(numbers[7])
Output
When we run the above program, we will get the following output−
-1 2
Explanation
The table numbers is a numerically indexed table.
Metatable is set on numbers table that contains a function for __index, which we call as a metamethod.
The metamethod does a simple job of looking up for an index. If a non-existing index is passed to the table, then a random value is returned, otherwise the corresponding value is printed.