luaiteratormeta-method

Make __call metamethod as iterator


I'm trying to emulate execution of certain functions from scripts of other app. That app have Lua library which contains function list(), it returns table where key is string UUID and value just string, like local tbl = { "0000..-0000-..." = "someString", etc... }. That table can be iterated in for loop, like

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

So the question, how do I implement __call metamethod to work as pairs() or next() etc.?

Thanks


Solution

  • Yes! I've managed to find answer to my question. I've found source code of library that I trying to replicate. It actually uses local variables to iterate through table

    Here is a code how I made lib.list() and lst work

    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