将 __call 元方法作为迭代器

Make __call metamethod as iterator

我正在尝试从其他应用程序的脚本中模拟某些功能的执行。该应用程序有 Lua 库,其中包含函数 list(),它 returns table 其中键是字符串 UUID,值只是字符串,如 local tbl = { "0000..-0000-..." = "someString", etc... }。那个table可以在for循环中迭代,比如

local lib = require("someLibrary.lua");

for key, value in lib.list() do
    -- do something with keys and values, like print
end

-- or it can be used like this

local tbl = lib.list();
for key, value in tbl do -- tbl works as pairs(tbl) and works exactly how code on top
    -- do something with keys and values, like print
end

所以问题是,我如何实现 __call 元方法以作为 pairs() 或 next() 等工作?

谢谢

pairs(tbl) returns next,tbl,nil.

也一样

setmetatable(tbl,{__call=function (t) return next,t,nil end})

然后你可以写

for key, value in tbl() do
        print(key, value)
end

我认为你无法避开那里的 ()

是的!我设法找到了我的问题的答案。我找到了我试图复制的库的源代码。它实际上使用局部变量来遍历 table

这是我如何使 lib.list()lst 工作的代码

function lib.list(filter, exact)
    if filter == nil then filter = '' end;
    if exact == nil then exact = false end;

    local list = Component.list(filter, exact); -- just gets table from app that written in C#, treat like someClass.getSomeTable()

    local list_mt = {}; -- metatable that assigns to above "list" table
    local key = nil; -- key that will be used in iterator

    function list_mt.__call() -- __call metamethod for "list" table
        key = next(list, key);
        if key then
            return key, list[key]
        end
    end

    return setmetatable(list, list_mt); -- return table with assigned metatable that contains __call metamethod
end