So this one might seem a bit tricky, but I'm trying to figure out how to make a fully "read only" table. I know to fully lock a table, I could just say something like this:
local realTable = {x = 1,y = 2,z = 3}
local fake = setmetatable({},{
__index = realTable, -- Reference to original table
__newindex = function(t,k,v)
-- Print this message, and ignore setting any values
print("Cannot change protected table")
end
})
print(fake.x) -- > 1
fake.x = 5 -- > "Cannot change protected table"
fake.x = nil -- > "Cannot change protected table"
So the code above works, however this is still a problem when using nested tables. Say I had a library with the following content:
-- Now I want to make it so you can't change library.workspace, OR any value within the library.workspace table.
local library = {
workspace = {x = 1, y = 2, z = 3},
}
If I applied my original method in my first example to the code above, it will only work for that library table, not the tables within it. For example:
local library = {
workspace = {x = 1,y = 2,z = 3}
}
local fake = setmetatable({},{
__index = library, -- Reference to original table
__newindex = function(t,k,v)
-- Print this message, and ignore setting any values
print("Cannot change protected table")
end
})
print(fake.workspace) -- > "table:hex"
fake.workspace = nil -- > "Cannot change protected table")
-- But...
fake.workspace.x = nil -- > This will change the value, I don't want to allow that.
print(fake.workspace.x) -- > Now this will be nil
Question
So, is there any way to make it so you can lock nested tables the same way as the initial table? Or would I have to create a metatable for each individual table inside each table? Because that seems like a fairly impractical method if you're working with a large scale of nested tables (which I am).
So if anyone out there has any insight on this, I'd really appreciate it!

1 comment
Close enough (*)