i know you're able to do constant variables in lua now with <const>, but they seem to only work with local variables:
local myNumber <const> = 10 -- This works perfectly fine
myGlobalNumber <const> = 10 -- This causes an error
Is it possible to have constant global variables as well?
myGlobalNumber <const> = 10
The point of the
<const>local variable attribute is to allow Lua to check, at "load" time (when you calldofile/load/requireor similar), whether a local variable is not being mutated - that is, whether the only assignment is the initial one at declaration time. It is a tool to help programmers (1) express intent (2) get slightly more "load time" checking than just syntactic checks.This works for
localvariables precisely because they are local. They are visible only within function scope. This means Lua has all the information it needs when you load a "chunk" of code (effectively a function body) to check whether it abides by the static (load time) rules of<const>."Globals" / "environmental variables" (as I like to call them) are effectively just syntactic sugar for accessing fields in the
_ENV(usually_G) table. As such, they are much more dynamic than local variables. You could do_G[some .. complex .. expression] = 42, for example. With global variables, just as with any other table fields, Lua does not have all the information it needs at load time. To begin, it does not even know which fields your code will set or get. Even if it knew this, or limited itself to the<name>syntax, that would still be insufficient. Consider loading a file where a certain global variable that was not set yet is used (perhaps in some callback where the author knows it will be available in time). Lua can not warn about this at the time the file is loaded. (It could, at best, try to warn when the file containing the conflicting constant definitions was loaded, then warn when subsequent files are loaded.)As ESkri has said, you can implement run-time checks to guard against accessing constant global variables via a metatable. That could look something like this:
However, this is probably a bad idea:
Instead, I would recommend the use of static analysis tools such as Luacheck, which lets you specify [read-only global variables in its configuration file, and also supports a
new read globalsinline option to add read-only global variables, similar to a "constant" definition. Example:it should be noted that while options are limited in scope to files, the
read_globalconfiguration field is per-"project" (folder) you're running Luacheck in. To establishpias a read-only global project-wide, you could setread_globals = {"pi"}, then use-- luacheck: globals pito make an exception wherepiis defined (followed by-- luacheck: new read globals pito revoke that exception afterwards).