Setmetatable
- 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
__index
operator 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 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.