PICO-8 Wiki
m (code tags)
Tag: Source edit
(split this into inline example & extrernal samples/references)
Tag: Source edit
Line 118: Line 118:
   
 
== Examples ==
 
== Examples ==
The [https://www.lua.org/pil/13.1.html Lua documentation on metatables] includes an example of implementing a set container type, using metamethods to implement set unions and intersections with the <code>+</code> and <code>*</code> operators.
 
 
The [https://www.lua.org/pil/16.html Lua documentation on objects] demonstrates how to use the <code>__index</code> metamethod to implement inheritance.
 
 
geckojsc posted [http://www.lexaloffle.com/bbs/?tid=3342 a metatable tutorial demonstrating adding and subtracting vector values].
 
 
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
 
-- default attribute values for a "pixel" class
 
-- default attribute values for a "pixel" class
Line 151: Line 145:
 
print(p2.y) -- 100
 
print(p2.y) -- 100
 
</syntaxhighlight>
 
</syntaxhighlight>
  +
  +
== External samples & references ==
  +
 
The [https://www.lua.org/pil/13.1.html Lua documentation on metatables] includes an example of implementing a set container type, using metamethods to implement set unions and intersections with the <code>+</code> and <code>*</code> operators.
  +
 
The [https://www.lua.org/pil/16.html Lua documentation on objects] demonstrates how to use the <code>__index</code> metamethod to implement inheritance.
  +
 
On the PICO-8 forums, user '''geckojsc''' posted [http://www.lexaloffle.com/bbs/?tid=3342 a metatable tutorial demonstrating adding and subtracting vector values].
   
 
== See also ==
 
== See also ==

Revision as of 01:46, 24 August 2021

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

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 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
__idiv
__mod
__pow
__and
__or
__xor
__shl
__shr
__lshr
__rotl
__rotr
__concat

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

(Respectively: +, -, *, /, \, %, ^, &, |, ^^, <<, >>, >>>, <<>, >><, ..)

__unm

__not
__peek
__peek2
__peek4

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

__ipairs function(table) 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

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

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