I've found some places on the web saying that operators in Lua are overloadable but I can't seem to find any example.
Can someone provide an example of, say, overloading the + operator to work like the .. operator works for string concatenation?
EDIT 1: to Alexander Gladysh and RBerteig:
If operator overloading only works when both operands are the same type and changing this behavior wouldn't be easy, then how come the following code works? (I don't mean any offense, I just started learning this language):
printf = function(fmt, ...)
    io.write(string.format(fmt, ...))
end
Set = {}
Set.mt = {}    -- metatable for sets
function Set.new (t)
    local set = {}
    setmetatable(set, Set.mt)
    for _, l in ipairs(t) do set[l] = true end
    return set
end
function Set.union (a,b)
    -- THIS IS THE PART THAT MANAGES OPERATOR OVERLOADING WITH OPERANDS OF DIFFERENT TYPES
    -- if user built new set using: new_set = some_set + some_number
    if type(a) == "table" and type(b) == "number" then
        print("building set...")
        local mixedset = Set.new{}
        for k in pairs(a) do mixedset[k] = true end
        mixedset[b] = true
        return mixedset
    -- elseif user built new set using: new_set = some_number + some_set
    elseif type(b) == "table" and type(a) == "number" then
        print("building set...")
        local mixedset = Set.new{}
        for k in pairs(b) do mixedset[k] = true end
        mixedset[a] = true
        return mixedset
    end
    if getmetatable(a) ~= Set.mt or
        getmetatable(b) ~= Set.mt then
        error("attempt to 'add' a set with a non-set value that is also not a number", 2)
    end
    local res = Set.new{}
    for k in pairs(a) do res[k] = true end
    for k in pairs(b) do res[k] = true end
    return res
end
function Set.tostring (set)
    local s = "{"
    local sep = ""
    for e in pairs(set) do
        s = s .. sep .. e
        sep = ", "
    end
    return s .. "}"
end
function Set.print (s)
    print(Set.tostring(s))
end
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
Set.mt.__add = Set.union
-- now try to make a new set by unioning a set plus a number:
s3 = s1 + 8
Set.print(s3)  --> {1, 10, 20, 30, 50}
                The metatable function only works on tables, but you can use debug.metatable to set the strings metatable...
> mt = {}
> debug.setmetatable("",mt)
> mt.__add = function (op1, op2) return op1 .. op2 end
> ="foo"+"bar"
foobar
> 
Another approach is to use debug.getmetatable to augment the built-in string metatable (answering the question in the comment below):
~ e$ lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> debug.getmetatable("").__add = function (op1, op2) return op1 .. op2 end
> ="foo"+"bar"
foobar
> 
                        See the Metatables section of Lua Programming Manual and Metatables and Metamethods chapter of the Programming in Lua 2nd edition.
Note that for comparison operators operator overloading works only when both operand types are the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With