Skip to content

__len metamethod result is nil in Lua despite returning a number #186

@CodeSmile-0000011110110111

Description

Trying to return a plain number from the __len metamethod results in the value being nil:

var enumTable = new LuaTable();
var lenFunc = new LuaFunction("enum.__len", (context, token) =>
{
    Console.WriteLine("enum.__len called ...");
    return new ValueTask<Int32>(context.Return(3));

});
enumTable.Metatable = new LuaTable();
enumTable.Metatable[Metamethods.Len] = lenFunc;
state.Environment["testEnum"] = enumTable;

Test script:

print(tostring(testEnum))
print("len = " .. tostring(#testEnum))

Output:

table: 27252167
enum.__len called ...
len = nil

If I do the setup entirely in Lua, it returns the expected result:

local t = {}
local mt = { __len = function(t) return 123 end }
setmetatable(t, mt)
print(tostring(#t))

Output: 123

Using 0.5 dev branch, pulled today. Confirmed by typing this in the solution's ConsoleApp1 sandbox project.

In case it helps, this is the entire output:

Source Code --------------------------------------------------
print(tostring(testEnum))
print("len = " .. tostring(#testEnum))


local t = {}
local mt = { __len = function(t) return 123 end }
setmetatable(t, mt)
print(tostring(#t))

Chunk[0]==================================================
Parameters:0
Code --------------------------------------------------
[0]     1               GETTABUP 0 0 -1
[1]     1               GETTABUP 1 0 -2
[2]     1               GETTABUP 2 0 -3
[3]     1               CALL 1 2 0
[4]     1               CALL 0 0 1
[5]     2               GETTABUP 0 0 -1
[6]     2               LOADK 1 3
[7]     2               GETTABUP 2 0 -2
[8]     2               GETTABUP 3 0 -3
[9]     2               LEN 3 3
[10]    2               CALL 2 2 2
[11]    2               CONCAT 1 1 2
[12]    2               CALL 0 2 1
[13]    5               NEWTABLE 0 0 0
[14]    6               NEWTABLE 1 0 1
[15]    6               CLOSURE 2 0
[16]    6               SETTABLE 1 -5 2
[17]    7               GETTABUP 2 0 -6
[18]    7               MOVE 3 0
[19]    7               MOVE 4 1
[20]    7               CALL 2 3 1
[21]    8               GETTABUP 2 0 -1
[22]    8               GETTABUP 3 0 -2
[23]    8               LEN 4 0
[24]    8               CALL 3 2 0
[25]    8               CALL 2 0 1
[26]    8               RETURN 0 1
LocalVariables --------------------------------------------------
[0]     t       14      27
[1]     mt      17      27
Constants --------------------------------------------------
[0]     print
[1]     tostring
[2]     testEnum
[3]     len\ =\
[4]     __len
[5]     setmetatable
UpValues --------------------------------------------------
[0]     _ENV    1       0

Chunk[0]==================================================
Parameters:1
Code --------------------------------------------------
[0]     6               LOADK 1 0
[1]     6               RETURN 1 2
[2]     6               RETURN 0 1
LocalVariables --------------------------------------------------
[0]     t       0       3
Constants --------------------------------------------------
[0]     123
UpValues --------------------------------------------------

Output --------------------------------------------------
table: 27252167
enum.__len called ...
len = nil
123
Result --------------------------------------------------
End --------------------------------------------------

Process finished with exit code 0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions