In Lua, member access works like this:
- Check if the key exists in the table, if it does, return the corresponding value
- Check if the table has a metatable, and inside a field called
__index
, if it does:- If
__index
is itself a table, lookup the key in that. - If
__index
is a function, call it with the table and key.
- If
So this is how you can implement getters:
- Set the metatable of new objects to a table you have access to
- Implement the
__index
method this way:- Check if the key exists in your prototype table, it essentially contains normal member methods
- 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)
Output:
Complex(1 + 3i) Complex(2 + 1i)
Complex(3 + 4i)
5.0
Top comments (0)