Arithmetic Metamethods Part 1
Part of the Logic & Flow section of Coddy's Lua journey — lesson 21 of 54.
You've learned how to customize what happens when you print a table using __tostring. Now you'll discover that metatables can also define what happens when you use arithmetic operators like + and - on your tables.
Normally, if you try to add two tables together with the + operator, Lua will give you an error because it doesn't know how to add tables. But with arithmetic metamethods, you can define exactly what addition means for your custom data types.
The __add metamethod controls addition behavior. When Lua encounters the + operator between two values and at least one has a metatable with __add, it calls that function instead of producing an error:
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- Output: 4 6The __add function receives two arguments: the left operand and the right operand. In this example, it creates a new table with x and y values that are the sum of the corresponding values from both input tables.
Similarly, the __sub metamethod controls subtraction with the - operator:
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- Output: 2 2This ability to define custom operator behavior is called operator overloading.
Challenge
EasyWrite a function addVectors that takes x1, y1, x2, and y2 and returns the result of adding two vectors together.
Create two vector tables with the given coordinates, attach a metatable with the __add metamethod to enable vector addition, add them using the + operator, and return the result as a formatted string.
Logic:
- Create the first vector table with keys
x = x1andy = y1 - Create the second vector table with keys
x = x2andy = y2 - Create a metatable with
__addthat takes two vectors and returns a new table withx = a.x + b.xandy = a.y + b.y - Attach the metatable to both vector tables using
setmetatable() - Add the two vectors using
v1 + v2 - Return the result as a string in the format
"x y"(the x and y values separated by a space)
Parameters:
x1(number): The x-coordinate of the first vectory1(number): The y-coordinate of the first vectorx2(number): The x-coordinate of the second vectory2(number): The y-coordinate of the second vector
Returns: The sum of the two vectors as a string in the format "x y" (string)
Cheat sheet
Metatables can define what happens when you use arithmetic operators like + and - on tables. This is called operator overloading.
The __add metamethod controls addition behavior with the + operator:
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- Output: 4 6The __add function receives two arguments: the left operand and the right operand.
The __sub metamethod controls subtraction with the - operator:
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- Output: 2 2Try it yourself
function addVectors(x1, y1, x2, y2)
-- Write code here
end
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Advanced Table Iteration
Iterating with pairs()Iterating with ipairs()pairs() vs. ipairs()Recap - Character Sheet4Introduction to Metatables
What is a Metatable?setmetatable & getmetatableThe __index MetamethodThe __newindex MetamethodThe __tostring MetamethodArithmetic Metamethods Part 1Arithmetic Metamethods Part 2Recap - Read-Only Table2More Table Library Functions
table.concat()table construction & unpack()table.sort()Custom Sorting with FunctionsRecap - High Score Board