🎓 A1Learner
🔍
0 of 52 lessons completed

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?