luametatable

Lua the __ipairs function implemented does not end the loop


I made an empty table, and using ipairs to access it will call other functions, but I don't know how to end the loop, when the loop proceeds to the last element, it still continues

local arr = {}
arr = setmetatable(arr, {
    __len = function(tbl)
        return 5
    end,
    __index = function(tbl, index)
        return 1
    end,
    __ipairs = function(tbl)
        local function iter(array, index)
            index = index + 1
            local value = nil
            if index <= #array then
                value = 1
            end
            if nil ~= value then return index, value end
        end

        return iter, tbl, 0
    end
})
for _, v in ipairs(arr) do
    print(_, v)
end

enter image description here


Solution

  • In Lua 5.3, the __ipairs metamethod has been deprecated, see https://www.lua.org/manual/5.3/manual.html#8.2

    In Lua 5.4 it has been removed. That means, it will be ignored, and is only relying on __index, which returns a constant 1 and thus remains stuck.

    A solution would be to use pairs:

    local arr = {}
    arr = setmetatable(arr, {
        __len = function(tbl)
            return 5
        end,
        __index = function(tbl, index)
            return 1
        end,
        __pairs = function(tbl)
            local function iter(array, index)
                index = index + 1
                local value = nil
                if index <= #array then
                    value = 1
                end
                if nil ~= value then return index, value end
            end
    
            return iter, tbl, 0
        end
    })
    for _, v in pairs(arr) do
        print(_, v)
    end