Search code examples
luaiterationtraversal

Is there a way to block an iteration of a table in Lua 4.0 ? (or how to prevent the access of table content)


I want to lock the access of a table content in Lua 4.01. Unfortunately I can't upgrade to Lua 5.xx.

I was thinking to use tag method (old metatable/metamethod mechanism of Lua) but it is still possible to traverse the table without triggering tagmethods using for loop (for ie,e in table do ...). It's like for statement uses rawget to access the table content.

Is there a way to lock the access? I know it would be possible using the C API but it's not really possible for the end-user.

Thanks


Solution

  • Using a table as un upvalue is a way to control data visibility. See Visibility and Upvalues in the Lua 4.0 Reference Manual.

    You maintain your data in a table local to a function. That table can’t be seen outside of that function.

    An example:

    function a()
        local t = {data = 123}
    
        return function()
            print(t.data)
        end 
    end
    

    Then:

    b = a()
    b() -- prints “123”
    

    Bad practice here to just use letters for function names, but it gets the point across: b is just the table returned from calling a. But this b, when called, prints the data stored in a’s local table t. There is no other way to access t, so in this way you can control table access. Add more functionality (setters, getters, other logic) to a’s return table to control access.

    Another Example

    Showing getter and setter access:

    function a()
        local t = {data = nil}
    
        local function set(data)
            t.data = data
        end
    
        local function get()
            return t.data
        end
    
        return {
            set = set,
            get = get
        }
    end
    
    b = a()
    b.set("abc")
    print(b.get())
    b.set(123)
    print(b.get())
    

    This prints:

    abc
    123