5
votes

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
1
possible duplicate of Lua override # for stringsLarry Battle
@LarryBattle Not really a duplicate, here the operand is not a string, but a table.Yu Hao
Your code works fine in the Lua live demo.lhf

1 Answers

6
votes

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