How to define immutable / constant variables

Ever wanted to make immutable / constant variables, variables that can’t be changed that have true read-only permission levels?

You’ve probably searched through the Lua or Lua-Users documentation page on how to do this with metatables where when you __index you create a proxy table and every time that table is modified you’re calling __newindex with an error message inside. __metatable could also return the error message whenever getmetatable() is called essentially locking everything. However there’s a catch…

lua-users wiki: Read Only Tables
Programming in Lua : 13.4.5

As shown in the Lua-Users documentation, this does not offer true read-only permission levels and in fact can still be modified with table.insert() and rawset(). The documentation tells us that in order for us to get true read-only capability, we need to do this on the C side.

Roblox has done that for us!

This has not been documented anywhere but there is a table.freeze() and table.isfrozen() function for this purpose.

table.freeze() locks a table making it read-only (does not lock the inner nested tables).

table.isfrozen() returns a bool value; true or false based on weather or not the table has been locked using table.freeze().

Creating constant ‘variables’ however is probably a little bit misleading, but you can definitely mimic this behaviour with locking the table with the variables that you don’t want to modify:

local const = {
	HELLO = "Hello world!",
	YAY = 25,
	IMMUTABLE = "I am immutable"

print(table.isfrozen(const)) -- Output: true
print(const.HELLO) -- Output: Hello World
const.HELLO = "Bye world!" -- ServerScriptService.Script:10: Attempt to modify a readonly table

Now we have created something that does not get affected by table.insert() nor rawset()!

Keep in mind that if you nest tables within this locked table, those tables will need to be locked as well.


yooo that’s nice, I used to use while true do to lock variables lol

Also, is there an “unfreeze” function?

No, there isn’t. However, you can simply override the reference to the “const” table with a clone of itself if you really want to, this works with the same principle as overriding Luas built in globals (like “table”) as they too can be overridden with a reference to another variable but not its inner instances.

1 Like