Lua Metamethods: Comparison
Comparison metamethods let a table respond to equality and order tests. They define when two table values count as equal or when one counts as smaller.
Equality compares matching fields
Two vectors share one metatable. Their equality field compares 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.__eq = function(a, b)
return a.x == b.x and a.y == b.y
end
local a = newvec(3, 4)
local b = newvec(3, 4)
print(a == b)
print(a == newvec(3, 5))Smaller compares field totals
Two vectors share one metatable. Their smaller field compares the sum of the fields.
local vecmt = {}
local function newvec(x, y)
local v = {x = x, y = y}
setmetatable(v, vecmt)
return v
end
vecmt.__lt = function(a, b)
return a.x + a.y < b.x + b.y
end
local a = newvec(1, 2)
local b = newvec(4, 5)
print(a < b)
print(b < a)Smaller or equal allows equal totals
Two vectors share one metatable. Their smaller or equal field compares the sum of the fields.
local vecmt = {}
local function newvec(x, y)
local v = {x = x, y = y}
setmetatable(v, vecmt)
return v
end
vecmt.__le = function(a, b)
return a.x + a.y <= b.x + b.y
end
local a = newvec(1, 2)
local c = newvec(2, 1)
local b = newvec(4, 5)
print(a <= c)
print(a <= b)
print(b <= a)Example
local vecmt = {}
local function newvec(x, y)
local v = {x = x, y = y}
setmetatable(v, vecmt)
return v
end
vecmt.__eq = function(a, b)
return a.x == b.x and a.y == b.y
end
vecmt.__lt = function(a, b)
return a.x + a.y < b.x + b.y
end
vecmt.__le = function(a, b)
return a.x + a.y <= b.x + b.y
end
local a = newvec(2, 3)
local b = newvec(2, 3)
local c = newvec(5, 5)
print(a == b)
print(a < c)
print(c <= a)
print(a <= b)Key points
- Shared metatable: equality and order fields apply only when both values share the same metatable.
- __eq: the field Lua calls to test two values for equality.
- __lt: the field Lua calls to test whether one value is smaller than another.
- __le: the field Lua calls to test whether one value is smaller than or equal to another.
- Total: a comparison can reduce a vector to one number, such as the sum of its fields.
In this example, three vectors share one metatable with three comparison fields. The first two vectors hold equal fields, so they test equal. The third vector has a larger total, so it tests larger and not smaller or equal.
Note
the equality field is ignored when the two values do not share one metatable.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
Two vectors hold equal fields but have different metatables. What does equality return?