Difference between revisions of "Lua: Metatables"
m (was i drunk when i wrote this) |
(Cleaning up) |
||
Line 1: | Line 1: | ||
{{Lua}} | {{Lua}} | ||
− | '''Metatables''' are a | + | '''Metatables''' are a form of [[Lua: Tables|table]] that may be attached to any other table, including itself. |
+ | |||
+ | An individual table may only have one metatable attached, but that metatable may have its own metatable, and this may be cascaded indefinitely. An individual metatable may be attached to any number of tables, however. | ||
+ | |||
+ | The primary purpose of metatables is to allow tables to be added together, an operation that is by default impossible. | ||
+ | |||
<source lang="lua" enclose="div">table1 = {1, 2, 3} | <source lang="lua" enclose="div">table1 = {1, 2, 3} | ||
table2 = {10, 20, 30} | table2 = {10, 20, 30} | ||
− | table3 = table1 + table2 -- error | + | table3 = table1 + table2 -- Returns an error</source> |
− | + | ||
− | |||
− | + | Because tables may contain any number of separate non-nil types of data, adding tables is by default impossible, and will always return an error, due to the overall impracticality of doing so. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | To allow tables to be added together, the [[Lua: Metamethods|metamethod]] ''__add'' must be defined within a metatable, and that metatable must then be appended to a regular table: | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | '' '' | |
− | return setmetatable(t_data, mt) | + | == Example code == |
+ | <div style='width: 60%; margin-left: 5%; background: #f8f8f8; border: 1px solid #444; padding: 8px;'><source lang="lua" enclose="div">function newTable(t_data) | ||
+ | return setmetatable(t_data, mt) -- Assigns the same metatable to every table made with this function | ||
end | end | ||
− | + | metatable = { | |
__add = function (a, b) | __add = function (a, b) | ||
− | local sum = newTable { } | + | local sum = newTable { } -- This is the value we will be returning. |
− | for i = 1, math.max(#a, #b) do -- | + | for i = 1, math.max(#a, #b) do -- runs as long as entries exist in the larger table |
− | sum[i] = (a[i] or 0) + (b[i] or 0) -- | + | sum[i] = (a[i] or 0) + (b[i] or 0) -- adds one table entry to its correspondent |
end | end | ||
return sum | return sum | ||
Line 60: | Line 38: | ||
table1 = newTable {1, 2, 3} | table1 = newTable {1, 2, 3} | ||
table2 = newTable {10, 20, 30} | table2 = newTable {10, 20, 30} | ||
− | table3 = table1 + table2 -- valid | + | table3 = table1 + table2 -- valid after much headache |
− | |||
− | |||
− | |||
− | + | print(table3) -- Was it worth it?</source></div> |
Revision as of 01:29, 6 October 2009
Lua |
---|
Basics |
Intermediate |
Advanced |
|
XLua |
Add to this template |
Metatables are a form of table that may be attached to any other table, including itself.
An individual table may only have one metatable attached, but that metatable may have its own metatable, and this may be cascaded indefinitely. An individual metatable may be attached to any number of tables, however.
The primary purpose of metatables is to allow tables to be added together, an operation that is by default impossible.
table1 = {1, 2, 3}
table2 = {10, 20, 30}
table3 = table1 + table2 -- Returns an error
Because tables may contain any number of separate non-nil types of data, adding tables is by default impossible, and will always return an error, due to the overall impracticality of doing so.
To allow tables to be added together, the metamethod __add must be defined within a metatable, and that metatable must then be appended to a regular table:
Example code
function newTable(t_data)
return setmetatable(t_data, mt) -- Assigns the same metatable to every table made with this function
end
metatable = {
__add = function (a, b)
local sum = newTable { } -- This is the value we will be returning.
for i = 1, math.max(#a, #b) do -- runs as long as entries exist in the larger table
sum[i] = (a[i] or 0) + (b[i] or 0) -- adds one table entry to its correspondent
end
return sum
end,
__tostring = function (t)
return table.concat(t, " ")
end,
}
table1 = newTable {1, 2, 3}
table2 = newTable {10, 20, 30}
table3 = table1 + table2 -- valid after much headache
print(table3) -- Was it worth it?