FANDOM


setmetatable( tbl, metatbl )
Updates the metatable for a table.
tbl
The table whose metatable to modify.

metatbl
The new metatable.

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

As of v0.1.6, PICO-8 does not support overwriting the __tostring metamethod. Tables cannot be concatenated with strings, nor can they be printed directly. You must explicitly convert your custom value types to a string before using them in this way.

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 Edit

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 rawget()

__newindex function(table, key, value)

Can also be a table.

Used when writing a non-existing key to the table.

Can be bypassed via rawset()

__len function(table) Called when getting the length of the table (via #).

Can be bypassed via rawlen()

__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 rawequal()

__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

__mul

__div

__mod

__pow

function(value1, value2) Called when performing arithmetic on the table.

(Respectively: +, -, *, /, %, ^)

__unm function(table) Called when negating the table (via -).
__concat function(value1, value2) Called when concatenating the table (via ..).
__call function(table, ...) Called when calling the table as if it were a function.
__tostring function(table) Only implemented in 0.1.12d and up (not released yet!)

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 next() directly.

__ipairs function(table) Only implemented in 0.1.12d and up (not released yet!)

Called when calling ipairs() on the table.

__metatable any value Returned instead of the real metatable when calling getmetatable().

Also, its presence causes setmetatable() to fail with an error.

__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 Edit

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.

geckojsc posted a metatable tutorial demonstrating adding and subtracting vector values.

-- default attribute values for a "pixel" class
pixel = {
  x = 0,
  y = 0,
  c = 7
}
 
-- the pixel class constructor
function pixel:new(o)
  self.__index = self
  return setmetatable(o or {}, self)
end
 
-- using the pixel class
p1 = pixel:new()
print(p1.x)   -- 0
print(p1.y)   -- 0
 
-- 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

See also Edit

Community content is available under CC-BY-SA unless otherwise noted.