- Updates the metatable for a table.
- tbl
-
- The table whose metatable to modify.
- metatbl
-
- The new metatable.
- return-value
-
- The same tbl that was passed in.
In Lua, tables are general purpose objects that contain values and can be manipulated with operators. The default behaviors of operators on a table value are stored in its metatable, using keys such as __index that refer to functions that perform the operator's task.
The setmetatable() function updates the metatable for a table, allowing you to customize the built-in operations. This has several useful applications for creating custom value types in Lua. For example, you can:
- Define a vector data type that supports arithmetic operators for addition and subtraction
- Set comparison operators on a new value type to use it with a generic sorting routine, such as sorting displayable objects by their display depth
- Implement inheritance: construct objects (tables) that refer to another table as a prototype (or class) by setting the
__indexoperator to access the prototype's properties
PICO-8 supports overwriting the __tostring metamethod. Tables can now be concatenated with strings, or printed directly.
PICO-8 includes Lua's rawget(), rawset(), rawlen(), and rawequal() functions, which ignore custom __index, __newindex, __len, and __eq metamethods, respectively.
Note: The return value is just the input, tbl, given back to you, which can be convenient in pseudo-constructors. See pixel:new() in the example below for a demonstration.
Metamethods[]
A summary of the lua metamethods, as they pertain to pico-8.
| __index | function(table, key)
Can also be a table. |
Used when reading a non-existing key from the table.
Can be bypassed via |
| __newindex | function(table, key, value)
Can also be a table. |
Used when writing a non-existing key to the table.
Can be bypassed via |
| __len | function(table) | Called when getting the length of the table (via #).
Can be bypassed via |
| __eq | function(table1, table2) | Called when comparing two distinct tables via == or !=,
but only if both have the same __eq metamethod. Can be bypassed via |
| __lt | function(value1, value2) | Called when comparing the table via < or >.
Also called when comparing via <= or >=, if __le isn't defined. |
| __le | function(value1, value2) | Called when comparing the table via <= or >=. |
| __add
__sub |
function(value1, value2) | Called when performing binary operations on the table.
(Respectively: +, -, *, /, \, %, ^, &, |, ^^, <<, >>, >>>, <<>, >><, ..) |
| __unm
__not |
function(table) | Called when performing unary operations on the table.
(Respectively: -, ~, @, %, $) |
| __call | function(table, ...) | Called when calling the table as if it were a function. |
| __tostring | function(table) | Called when calling tostr(), print() and printh() on the table.
|
| __pairs | function(table) | Called when calling pairs() on the table.
Can be bypassed by using |
| __ipairs | function(table) | Called when calling ipairs() on the table.
Can be bypassed by using |
| __metatable | any value | Returned instead of the real metatable when calling getmetatable().
Also, its presence causes |
| __gc | - | Appears to not be implemented in PICO-8. |
| __mode | "k"/"v"/"kv" | Specifies the table has weak keys/values.
(See lua reference manual for more details) |
Examples[]
-- default attribute values for a "pixel" class
pixel = {
x = 0,
y = 0,
c = 7
}
pixel.__index=pixel
-- the pixel class constructor
function pixel:new(o)
return setmetatable(o or {}, self)
end
-- using the pixel class
p1 = pixel:new()
print(p1.x) -- 0
print(p1.y) -- 0
print(p1.c) -- 7
-- use an instance of pixel to subclass it
-- (prototypical inheritance)
newpixel = pixel:new({y=100})
p2 = newpixel:new()
print(p2.x) -- 0
print(p2.y) -- 100
External samples & references[]
The Lua documentation on metatables includes an example of implementing a set container type, using metamethods to implement set unions and intersections with the + and * operators.
The Lua documentation on objects demonstrates how to use the __index metamethod to implement inheritance.
On the PICO-8 forums, user geckojsc posted a metatable tutorial demonstrating adding and subtracting vector values.
See also[]
getmetatable()rawset()rawget()rawlen()rawequal()- Metatables
- Tables
- Lua