Search code examples
lualua-tablemetatable

Lua table length function override not working


How does one change the length operator (#) for a table in Lua, the manual suggests assigning the __len function in a metatable and then assigning that metatable to the table I want to override, but this doesn't work as expected? I do not have the option to override this on the C side.

turtles = {1,2,3}
setmetatable(turtles, {__len = function(mytable) return 5 end})

print(#turtles)
--returns 3, should return 5

Solution

  • You must be using Lua 5.1. The __len metamethod on tables is supported since Lua 5.2.

    In Lua 5.1 reference manual, if the operand is a table, return the primitive table length directly.

    "len": the # operation.

    function len_event (op)
       if type(op) == "string" then
         return strlen(op)         -- primitive string length
       elseif type(op) == "table" then
         return #op                -- primitive table length
       else
         local h = metatable(op).__len
         if h then
           -- call the handler with the operand
           return (h(op))
         else  -- no handler available: default behavior
           error(···)
         end
       end
     end
    

    In Lua 5.2 reference manual, if the operand is a table, check if the __len metamethod is available.

    "len": the # operation.

    function len_event (op)
       if type(op) == "string" then
         return strlen(op)      -- primitive string length
       else
         local h = metatable(op).__len
         if h then
           return (h(op))       -- call handler with the operand
         elseif type(op) == "table" then
           return #op              -- primitive table length
         else  -- no handler available: error
           error(···)
         end
       end
     end