__add fires when you perform addition arithmetic on your table.
local t = { "a", "b", "c" }
local mt = {
__add = function(lhs, rhs)
local new = { }
for _, v in ipairs(lhs) do
table.insert(new, v)
end
for _, v in ipairs(rhs) do
table.insert(new, v)
end
return new
end
}
setmetatable(t, mt)
print(table.concat(t + { "d", "e", "f" })) -- abcdef
Instead of throwing an exception it adds the 2 tables together. When you change the behavior of an operator (based on operands) this is called operator overloading.
If you add two tables with the + operator, and the operand has an __add function in it’s metatable, that function will be called and its return value will be the result of the addition.
In this example I use tables as wrapper objects for strings and assign a metatable to them. I wrote the metatable’s add function such that adding two of these tables will concatenate their string values.
local s1 = {['value'] = "hello "}
local s2 = {['value'] = "world!"}
local mt = {}
function mt:__add(other)
return setmetatable({['value'] = self.value..other.value}, mt)
end
function mt:__tostring() -- for printing
return self.value
end
setmetatable(s1, mt)
setmetatable(s2, mt)
print(s1) -- hello
print(s2) -- world!
print(s1+s2) -- hello world!