質問

A beginner's question about Lua and metatables, with a example as simple as an Hello‑World, involving the len event, which unfortunately does not returns the expected result (I'm using Lua 5.1 installed from Ubuntu's official repository).

The case

Here is the example:

Test_Type = {};

function Test_Type.__len (o)
   return 1;
end;

function new_test ()
   local result = {};
   setmetatable(result, Test_Type);
   return result;
end;

do
   local a_test = new_test();
   print (#a_test);
   print(getmetatable(a_test).__len(a_test));
end;

And the result I get:

0
1

I was expecting the first print statement to display 1, but it displays 0, to my big surprise.

What did I missed?

According to Lua Reference Manual — Metatables and Metamethods, the # is equivalent to this:

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

So print (#a_test); and print(getmetatable(a_test).__len(a_test)); should result into the same, isn't it?

By the way, why is the above excerpt from the Reference Manual refers to metatable(op) while it should be getmetatable(op)? At least I've tried print(metatable(a_test).__len(a_test));, and it ends into an error.

Answer

As Nneonneo noticed, this is an issue with the Lua version in use. Lua 5.2 seems to be required for the above to work.

役に立ちましたか?

解決

From http://lua-users.org/wiki/LuaFaq:

Why doesn't the __gc and __len metamethods work on tables?

__len on tables is scheduled to be supported in 5.2. See LuaFiveTwo.

Since you're using 5.1, __len on tables does not work. Indeed, running your code on Lua 5.2 produces

1
1

as expected.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top