When does __add fire?

So I recently started learning about metatables and they are so cool!

I understand how __index and __newindex work, but I don’t how __add works.

The devhub just says: The + addition operator.

I have heard that I will never use it but I want to know what it does and when it fires.

__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.

1 Like

Basically its just what you did read. Here is a example of when it fires:

local tbl = {__add = function() print("a") end)}
tbl + 1
tbl + {}
-- Fired it twice
1 Like

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!
1 Like