__newindex doesn't catch editing a variable, alternatives?

Currently I’m trying to lock a metatable so that they cant set any of the current variables or add any. (I understand there is rawset and rawget to bypass this but this is just for more features) I expected __newindex to grab changing a variable inside that table but it doesn’t. Checking the API it clarifies this:


Is there any way to get when someone tries to change a variable in a metatable without a loop?

1 Like

Sorry, I wasn’t thinking when making this but I believe this is the way of doing it:

local table = { ... }

setmetatable({ }, {
    __index = function(self, k)
        return table[k]
    end,
    __newindex = function()
        return error("Newindex isn't allowed")
    end,
    __metatable = "Locked."
})
1 Like

You’ll need to use a proxy interface; for example:

local object = {}
local interface = setmetatable({}, {
    __index = function(self, key)
        return object[key]
    end,
    __newindex = function(self, key, value)
        assert(not object[key], "existing values cannot be changed")
        object[key] = value
    end,
})

Users will interact with object through interface.

8 Likes

@Dandystan beat me to it. And if you want the data to be hidden, you could wrap all of that in a function and return just the interface object. That will make the object data table hidden (i.e. private)

Thanks! yeah I wasn’t thinking straight when I made this but I did want all the data to be hidden so :+1:

Quick word of warning; this will break pairs! Keep that in mind - if you need to iterate, you have to use the object and not the interface.

5 Likes