lua

How to Extend Existing Types with Methods in Lua, Similar to Swift Extensions or JavaScript Prototypes?


In Swift, you can add methods to existing types using extensions, and in JavaScript, you can do the same using prototypes. How can I achieve a similar functionality in Lua?

I want to add a clamp function to numbers.

If this is not possible, please let me know.


Solution

  • From Lua, if the debug library is available, you can use debug.getmetatable and debug.setmetatable to change the metatables for non table types.

    As with any metatable, the __index metamethod can be used to make the object respond to key indexing.

    A cursory example. Note that in debug.getmetatable(0) and debug.setmetatable(0, mt), 0 is a chosen as an arbitrary number value. Passing any number value to these functions will work to access the metatable for the type.

    local mt = debug.getmetatable(0) or {}
    local methods = {}
    mt.__index = methods 
    
    function methods:clamp(lower, upper)
        if lower > self then return lower end
        if upper < self then return upper end
        return self
    end
    
    debug.setmetatable(0, mt)
    
    for i = 1, 5 do 
        local n = math.random(100)
        print(n, n:clamp(33, 66))
    end 
    
    88  66
    48  48
    46  46
    20  33
    70  66
    

    See Lua 5.4: 2.1 - Values and Types | 2.4 – Metatables and Metamethods | 6.10 – The Debug Library