Declaring global variables

Is there a difference between declaring a variable like this:

\_G.someVariable = something

vs this:

someVariable = something

I used to have a utility module that I had to import in every single file I needed to use it in. Then I started importing it once into main.lua and assign it to a global variable. Now I’m thinking of making the module itself global like this:

M = {} M.someVariable = something return M

Would it be considered a good practice to do it this way?

Hi,

While a bit inconvenient, best practice would be to include your utils module in each file.

But in the event that you don’t want to, the last example you show would result in M being a global, so returning it really has no use. As an example:

--utils.lua M = {} M.somevar = "Hello" --main.lua require("utils") print(M.somevar) --Hello

A better way might be to create your module and then globalize the return:

--utils.lua local M = {} M.somevar = "Hello" return M --main.lua M = require("utils") print(M.somevar)--Hello

-dev

I would avoid globals outright. Just require() the “utils” module in each other module you need to access a variable from it, and you’re golden. It’s just one extra line near the top… that’s it… and it avoids any global pitfalls.

Of course, use the version @Develephant suggests, not the global version (otherwise there’s no point).

[lua]

–utils.lua

local M = {}

M.somevar = “Hello”

return M

[/lua]

Brent

Thanks, guys. About the globals table, so I don’t need to declare my globals like this:

\_G.utils = require( "utils" )

_G.someVar and someVar are identical internally. You however create uncertainty when you do:

someVar = 10

Because you could intend it to be local and just forgot to pre-declare it before you used it. This is where most people get into trouble with global variables. By always prefixing _G. on the front, you are explicitly stating that “I am making this global on purpose”.  Now that still doesn’t mitigate against the performance issues with globals.

Doing _G.utils = require(“utils”) saves you some time when coding other modules, but you still have it occupying global memory instead of local memory and will take said performance hit. It will technically work. 

Personally I just require my data table module in every scene and module. It’s not that much more code.

Rob

I agree with Rob… it’s one tiny line… just require() it locally near the top of any module where you need it.

Hi,

While a bit inconvenient, best practice would be to include your utils module in each file.

But in the event that you don’t want to, the last example you show would result in M being a global, so returning it really has no use. As an example:

--utils.lua M = {} M.somevar = "Hello" --main.lua require("utils") print(M.somevar) --Hello

A better way might be to create your module and then globalize the return:

--utils.lua local M = {} M.somevar = "Hello" return M --main.lua M = require("utils") print(M.somevar)--Hello

-dev

I would avoid globals outright. Just require() the “utils” module in each other module you need to access a variable from it, and you’re golden. It’s just one extra line near the top… that’s it… and it avoids any global pitfalls.

Of course, use the version @Develephant suggests, not the global version (otherwise there’s no point).

[lua]

–utils.lua

local M = {}

M.somevar = “Hello”

return M

[/lua]

Brent

Thanks, guys. About the globals table, so I don’t need to declare my globals like this:

\_G.utils = require( "utils" )

_G.someVar and someVar are identical internally. You however create uncertainty when you do:

someVar = 10

Because you could intend it to be local and just forgot to pre-declare it before you used it. This is where most people get into trouble with global variables. By always prefixing _G. on the front, you are explicitly stating that “I am making this global on purpose”.  Now that still doesn’t mitigate against the performance issues with globals.

Doing _G.utils = require(“utils”) saves you some time when coding other modules, but you still have it occupying global memory instead of local memory and will take said performance hit. It will technically work. 

Personally I just require my data table module in every scene and module. It’s not that much more code.

Rob

I agree with Rob… it’s one tiny line… just require() it locally near the top of any module where you need it.