Lua Metamethods: Arithmetic
Arithmetic metamethods let a table respond to arithmetic operators. They define what plus, minus, and similar operators do for a table value.
Plus adds matching fields of two vectors
Two vectors share one metatable. Their plus field adds the x fields and the y fields.
local vecmt = {}
local function newvec(x, y)
local v = {x = x, y = y}
setmetatable(v, vecmt)
return v
end
vecmt.__add = function(a, b)
return newvec(a.x + b.x, a.y + b.y)
end
local a = newvec(1, 2)
local b = newvec(10, 20)
local c = a + b
print(c.x, c.y)Minus subtracts matching fields
Two vectors share one metatable. Their minus field subtracts the x fields and the y fields.
local vecmt = {}
local function newvec(x, y)
local v = {x = x, y = y}
setmetatable(v, vecmt)
return v
end
vecmt.__sub = function(a, b)
return newvec(a.x - b.x, a.y - b.y)
end
local a = newvec(10, 20)
local b = newvec(1, 2)
local c = a - b
print(c.x, c.y)Unary minus negates each field
Unary minus takes one value. Its field negates the x field and the y field.
local vecmt = {}
local function newvec(x, y)
local v = {x = x, y = y}
setmetatable(v, vecmt)
return v
end
vecmt.__unm = function(a)
return newvec(-a.x, -a.y)
end
local a = newvec(1, 2)
local b = -a
print(b.x, b.y)Example
local vecmt = {}
local function newvec(x, y)
local v = {x = x, y = y}
setmetatable(v, vecmt)
return v
end
vecmt.__add = function(a, b)
return newvec(a.x + b.x, a.y + b.y)
end
vecmt.__mul = function(a, b)
if type(a) == "number" then
return newvec(a * b.x, a * b.y)
else
return newvec(a.x * b, a.y * b)
end
end
local a = newvec(2, 3)
local b = a * 3
local c = a + newvec(1, 1)
print(b.x, b.y)
print(c.x, c.y)Key points
- Metatable: a table that holds special behavior for another table.
- Metamethod: a special field in a metatable that Lua calls for one operation.
- __add: the field Lua calls when two values are added with plus.
- Operands: the two values on either side of the operator reach the metamethod as its arguments.
- Result: an arithmetic metamethod should return the new value for the operation.
In this example, a vector is built with x and y fields. Multiplying by three scales both fields. Adding a second vector then adds the matching fields.
Note
Lua only applies the operator to a table when its metatable holds the matching field.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does a plus b do when a and b are vectors sharing a metatable with a plus field?