Difference between global variables, _G.var and var?

I searched but couldn't find an answer.
I thought declaring without local would make a variable global but I noticed that unless I use _G. I can't access the variables from another module.

_G.variables are commonly used by lua.

A variable without _G is also considered a global variable but I couldn't access it across two different files.

I'm wondering if this global variable is referred to as local elsewhere, which maybe causing one of your modules not to recognize it as global? You might want to check all your modules and search & check how this global variable is referenced/used in each module.

EDIT: Another thing I might try is to change the name of the global variable to something ridiculously unique, and see if it solves the problem, and if it does, then you know that the variable is used somewhere else (which you may not be fully aware of), causing the conflict.

Naomi

I use _G.variable to access music on and off from my option.lua worked fine but I would try to use local variable as much as possible to keep a clean app. But I think regarding your question the best answer comes from iolo72

^
iolo72 actually asked the question :)

@LeivaGames
I was the one who asked the question ;)

@Naomi
I will check for references.

To clarify the question, when I do this in module01.lua

1
  myVar = 1234

Silly me I read your post wrong I thought you said "A variable without _G is also considered a global variable but cant be access across two different files" So is why I said you had the best answer lol. This being said I think thats the way ill put it I havent recently tested on my new app but on my 1st app my global variable was not working across file so I _G and it worked like a charm.

I am having the same experience but even the Corona reference says otherwise.

http://developer.anscamobile.com/content/introduction#Global

Maybe I am misunderstanding the scope of "global"???

_G. could maybe be called a "super" global
php.net/manual/en/language.variables.superglobals.php

To access a global in another module, you must use "otherModule.globalVar"
To access the _G.Global you can call it using "_G.Global"

So in order of global-ness:
_G.Var
Var
Local Var

Hey iolo72, the problem might be the fact you are trying to get myVar from module01. I think main.lua is the very first file that gets processed (but then, I don't really know how & when required modules are processed, so I could be totally off.)

Anyhow, maybe the fact you state myVar = 1234 in module01 while trying to retrieve this value in main.lua might be the problem. If you swap this around (i.e., stating myVar = 1234 in main.lua and try retrieving the value in module01), I imagine it would work.

Naomi

Hey anddrewscott, that's interesting. Thanks for the link. I learn new thing every day.

I've been using global variable without using _G since I began my project. It's been working perfectly fine. Only difference with my case and iolo's is that I always define my global variable in main.lua, and have this global variable accessed from other module. No problem there.

That said, I finally decided to use _G (because I feel I understand it better now, and I feel comfortable using it). It was a very simple conversion process, because all I had was a myGlobalVariable table. All I had to do was replace myGlobalVariable. with _G. The net result for me was shortening the name of the variable. Heh.

Naomi

By the way, when I want to use global variable from other module, I localize it first, like so:

1
2
3
4
5
6
7
-- main.lua
_G.fontName1 = "myCustomFontHere"
 
--other module that uses the custom font
local fontName1 = _G.fontName1
 
-- After that, I simply use fontName1 (without _G. in front of it.)

@anddrewscott
Thanks for the explanation.

@Naomi
Yeah, that's what I've been doing. I really wish I don't have to use global variables but it's proving to be very difficult! :)

Hey, iolo, when I was cleaning after my lunch just now, a thought popped in to my head about this topic. Maybe you could try placing print statements inside module01 right after myVar is given the value of 1234, and also in main.lua like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
-- in module01.lua
myVar = 1234
print("in module01, myVar is now given value of " .. myVar)
 
-- in main.lua
print ("I'm about to require module01 in main.lua")
require("module01")
 
print ("module01 is already required at this point in main.lua")
print("main.lua says the value of myVar is " .. myVar)
 
-- at the very end of main.lua, add this too
print("the end of main.lua is reached")

Thanks, Naomi. I understand that _G variable works regardless of where it was declared or used, without having to use require("module"), which is a lazy way to go about when using global vars.

I just looked at what I wrote and the example I gave in the reply (#6) is incorrect (sorry, maybe I was high...)

What I meant to say was this:

module01.lua

1
2
3
4
function myFunction()
  myVar = 1234
  print("myVar")
end

Hey iolo, that's interesting. Have you tried this?

module01.lua

1
2
3
function myFunction()
  myVar = 1234
end

myVar; throws a syntax error.

This works though.

module01.lua

1
2
3
4
module(..., package.seeall)
function myFunction()
  myVar = 1234
end

Hey, iolo, you got me curious, and here's what I tried, and this one works too.

main.lua

1
2
3
4
5
6
7
8
local module01 = require ("module01")
print("myVar after module01 is required:  " .. tostring(myVar)) -- prints nil
 
module01.myFunction()
print("myVar after module01.myFunction() is called:  " .. tostring(myVar)) -- prints nil
 
myVar = module01.myFunction()
print("myVar after myVar = module01.myFunction() is called:  " .. tostring(myVar)) -- prints 1234

By the way, returning back to the original question -- I'm no longer sure if not having "local" in front of a variable makes it global. Not that I will stop placing "local" in front of variable, but it sure is confusing. This test project makes it look like myVar does not become global when it is used inside a function.

I also tried using _G. in front of myVar, and I got an interesting result:

main.lua

1
2
3
4
5
6
7
8
local module01 = require ("module01")
print("myVar after module01 is required:  " .. tostring(_G.myVar)) -- prints nil
 
module01.myFunction()
print("myVar after module01.myFunction() is called:  " .. tostring(_G.myVar)) -- prints 1234
 
myVar = module01.myFunction()
print("myVar after myVar = module01.myFunction() is called:  " .. tostring(_G.myVar)) -- prints 1234

Ah, here's another test. It looks like if I don't place local in front of a variable in main.lua, it will become global.

main.lua

1
2
3
4
5
6
7
8
local module01 = require ("module01")
myVar = 0;
print("calling module01.myFunction() in main.lua while myVar is still 0")
module01.myFunction()  -- prints value of myVar inside myFunction = 0
 
myVar = 1234;
print("calling module01.myFunction() in main.lua after myVar is set to 1234")
module01.myFunction() -- prints value of myVar inside myFunction = 1234

iolo, you really got me following this quest. I had to try one more test, and here's the result. module02 would recognize the value of myVar set by module01 even when main.lua doesn't recognize it. So... what is myVar? If it's global variable, then this must be the difference between super global (_G) and regular global (and regular global appears to be smaller in scope).

Anyhow, here's the test & result:

main.lua

1
2
3
4
print("in main.lua myVar = " .. tostring(myVar)) -- prints myVar = nil
local module02 = require ("module02")
module02.myFunction() -- prints myVar = 1234
print("in main.lua myVar = " .. tostring(myVar)) -- prints myVar = nil

Wow, that's a lot of testing!

You can't access a local function in a module from another module even if you require it because it is localized only to the module that it's declared in.

By using this method however (http://blog.anscamobile.com/2011/09/a-better-approach-to-external-modules/) it lets you localize functions and use it in another module. I have been using this and it works great. I also fixed a memory leak by switching.

At this point, using _G's makes things a lot easier than trying to use locals when passing data among modules. As long as I nil out the _G's after use seems to control memory leaks as well. I just gotta be careful not to go overboard with too many _G's.

Hey, iolo, when my game is done (meaning, when I have everything implemented and only last thing remaining is the final polishing), I will definitely look into localizing functions described in the link noted in post #22. I've read it before, and I couldn't quickly implement it -- it's probably because I haven't tried sorting it out properly in smaller test project first.

I'm also still learning how to properly pass parameters. Net result is, I don't create public/global functions in external modules. My functions are either a public/global function established in main.lua or a local function restricted to each external module. This must be part of the reasons I was able to purge memory leak concerns from my project.

Good to hear you've come to terms with _G. anyhow.

Cheers,
Naomi

views:2064 update:2011/11/17 9:28:17
corona forums © 2003-2011