Skip to content
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>
Clone this wiki locally