Learning Lua can be a little tricky. The idea of variables implicitly being global can be confusing for some people, so using new users often dropped the much-needed local keyword. If you are concerned about accidentally creating globals there is a quick and easy check you can do you show you when/where you are creating them!
To implement this we are going to create a new metatable for the globals table. If you didn’t already know, all globals in Lua are stored in a table called the “environment“. It is accessible anywhere in Lua by accessing a table called “_G“. The fact that all globals are stored in the same table allows us to take advantage of a nifty metamethod call __newindex.
- Use “rawset(myTable,key,value)” to skip this metamethod.
- (If the __newindex function does not set the key on the table (using rawset) then the key/value pair is not added to myTable.)
This is exactly what we’re looking for!
[lua]
setmetatable(_G, {__newindex =
function(self, key, value)
if not Engine:AllowGlobals() then
Engine:StopWithError(“Invalid Global created”)
else — Set value normally
rawset(self, key, value)
end
end
})
[/lua]
With this setup, you can see what this example will do:
[lua]
— OK
local testVar1 = 5
— Not OK, invalid global
testVar2 = 17
[/lua]
You can handle the invalid global creation however you want. In my case I called a function that would halt the game and present the user with an error where it occurred:
Another nice trick you can do is make a global function that will explicitly create a global. This clearly outlines when you are creating a new global and can make your code a bit easier to follow. A example of such a function looks like this:
[lua]
DeclareGlobal = function(name, value)
— Allow creation of our new global
Engine:SetGlobalCreation(true)
_G[name] = value
— Turn off global creation
Engine:SetGlobalCreation(false)
end
–[[ Example usage ]]
— Not OK
testGlobal = 5
— OK
DeclareGlobal(“testGlobal”, 5)
[/lua]
You can expand this idea to work with any table you’d like as well. While I won’t go into in this post, you could easily set up a system in which you must explicitly declare key/values in tables to help prevent erroneous variable creation.
Hopefully this can help a few people from bashing their head on their keyboard because of a few typos!