-
Notifications
You must be signed in to change notification settings - Fork 53
Metamethods
Roland edited this page Sep 27, 2016
·
3 revisions
Classes support metamethods as well as methods. Those metamethods are inherited by subclasses.
Let us use this example to build a minimalistic Vector
class.
local V = class("Vector")
-- Vector class constructor
function V:init(x, y)
self.x, self.y = x or 0, y or 0
end
-- Custom tostring function, to display vector instance components x and y
function V.__tostring(v)
return ("Vector <%.2f, %.2f>"):format(v.x, v.y)
end
-- Adds two vectors, component-wise
function V.__add(v1, v2)
local v = V()
v.x = v1.x + v2.x
v.y = v1.y + v2.y
return v
end
-- Substracts two vectors, component-wise
function V.__sub(v1, v2)
local v = V()
v.x = v1.x - v2.x
v.y = v1.y - v2.y
return v
end
-- Multiplies two vectors, component-wise
function V.__mul(v1, v2)
local v = V()
v.x = v1.x * v2.x
v.y = v1.y * v2.y
return v
end
-- Divides two vectors, component-wise
function V.__div(v1, v2)
local v = V()
v.x = v1.x / v2.x
v.y = v1.y / v2.y
return v
end
-- Unary minus vector (similar to vector multiplied by -1)
function V.__unm(v)
v.x = - v.x
v.y = - v.y
return v
end
-- Vector raised to power n, component-wise
function V.__pow(v, n)
v.x = v.x ^ n
v.y = v.y ^ n
return v
end
-- Let us create two instance of our vector class
local v1 = V(2, 0.5)
local v2 = V(1, 0.7)
-- Let us perform operations on those vectors
print(v1 + v2) -- outputs Vector <3.00, 1.20>
print(v1 - v2) -- outputs Vector <1.00, -0.20>
print(v1 * v2) -- outputs Vector <2.00, 0.35>
print(v1 / v2) -- outputs Vector <2.00, 0.71>
print(- v1) -- outputs Vector <-2.00, -0.50>
print(v1 ^ 2) -- outputs Vector <4.00, 0.25>
Lua 5.2 introduces new metamethods, such as __len
, __pairs
and __ipairs
. They are also supported by 30log.
Let us draw and example with __len
:
local V = class("Vector")
function V.__len(v)
return math.sqrt(v.x * v.x + v.y * v.y)
end
print(#V(1, 1)) -- outputs <1.412...>
print(#V(0, 1)) -- outputs 1
And another example with __pairs
:
local V = class("Vector")
-- Implements a custom iterator
function V.__pairs(v)
local key, value
return function()
key, value = next(v, key)
return key, value
end
end
local v = V(3, 7)
for key, value in pairs(v) do
print(key, value) -- outputs 'x, 3' and 'y, 7' (in random order)
end
Lua 5.3 introduces bitwise operators. They are also supported by 30log.
Let us draw an example with bitwise AND (&), bitwise OR (|), left shift (<<) and right shift (>>) :
local V = class("Vector")
function V.__band(v, n) return V(v.x & n, v.y & n) end
function V.__bor(v, n) return V(v.x | n, v.y | n) end
function V.__shl(v, n) return V(v.x << n, v.y << n) end
function V.__shr(v, n) return V(v.x >> n, v.y >> n) end
local v = V(2, 4)
print(v & 2) --outputs Vector <2.00, 0.00>
print(v | 3) --outputs Vector <3.00, 7.00>
print(v << 1) --outputs Vector <4.00, 8.00>
print(v >> 4) --outputs Vector <0.00, 0.00>