DEV Community

MixusMinimax
MixusMinimax

Posted on

Getters in Lua

In Lua, member access works like this:

  1. Check if the key exists in the table, if it does, return the corresponding value
  2. Check if the table has a metatable, and inside a field called __index, if it does:
    1. If __index is itself a table, lookup the key in that.
    2. If __index is a function, call it with the table and key.

So this is how you can implement getters:

  1. Set the metatable of new objects to a table you have access to
  2. Implement the __index method this way:
    1. Check if the key exists in your prototype table, it essentially contains normal member methods
    2. Check if the key exists with the prefix get_, and call it.

Example:

Complex = { mt = {}, prototype = {} }
Complex.mt.prototype = Complex.prototype
function Complex.mt.__index(table, key)
    local prototype = getmetatable(table).prototype
    local inProtoType = prototype[key]
    if inProtoType ~= nil then return inProtoType end
    local getterKey = "get_" .. key
    local getter = prototype[getterKey]
    if getter ~= nil then return getter(table) end
    return nil
end

function Complex:new(o)
    o = o or {}
    local result = {}
    result.re = o.re or 0
    result.im = o.im or 0
    setmetatable(result, self.mt)
    return result
end

function Complex.mt:__tostring()
    return "Complex(" .. self.re .. " + " .. self.im .. "i)"
end

function Complex.mt:__add(o)
    o = o or {}
    local re = o.re or 0
    local im = o.im or 0
    return Complex:new { re = self.re + re, im = self.im + im }
end

function Complex.prototype:get_magnitude()
    return math.sqrt(self.re ^ 2 + self.im ^ 2)
end

local z = Complex:new { re = 1, im = 3 }
local w = Complex:new { re = 2, im = 1 }

print(z, w)

print(z + w)

print((z + w).magnitude)
Enter fullscreen mode Exit fullscreen mode

Output:

Complex(1 + 3i) Complex(2 + 1i)
Complex(3 + 4i)
5.0
Enter fullscreen mode Exit fullscreen mode

Top comments (0)