setmetatable( tbl, metatbl )

Updates the metatable for a table.

The table whose metatable to modify.
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 Pico-8 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 does not support Lua's rawget() or rawset() (which would ignore custom __index and __newindex metamethods).

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.

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