Does using removeSelf() (or nilling) a display object (or table) ALSO nil all its indexes?

I like to use extra properties for my display objects for keeping track of stats, and also for references to event listeners, timers, and maybe even other display objects.

For example:

[lua] enemy = display.newImageRect(“enemy.png”, 30, 60)

– touch handler
enemy.touch = enemyTouchHandler
enemy.touchListener = enemy:addEventListener( “touch”, enemy)

– timer for animation
enemy.animationTimer = timer.performWithDelay ( 500, function() return animateEnemy( enemy ) end, 0)

enemy.name = “enemy”
enemy.poweredUp = false
enemy.status = “alive”
enemy.type = “default”
enemy.speed = 25
enemy.health = 100[/lua]

When I want to destroy the enemy, I do the following:

  1. Cancel the timer and touch listener (although I don’t think I need to cancel the touch listener as it’s taken care of by removeSelf())
  2. use enemy:removeSelf(), then enemy = nil

So is the REFRERNCE to the timer removed? And are all my properties removed? I guess what I’m asking is if enemy.animationTimer is set to nil? What if my reference to the timer was one level deeper, like enemy.timers.animation?

Similarly, if I just have a table (that’s not a display object), I can’t use removeSelf(), so I just nil the table. When I nil a table, does it ALSO nil all its indexes (all the way down)? This is especially important if I use an index as a reference to a timer or display object…

[lua] table1 = {}
table1.timers = {}
table1.timers.name = “a table to hold the timers”
table1.timers.timer1 = timer.performWithDelay ( 500, doSomething, 0 )

timer.cancel (table1.timers.timer1) – timer is cancelled but memory isn’t freed since there’s still a reference to it
table1 = nil – does this also nil out table1.timers.name, and table1.timers.timer1?[/lua]

Does that last line above get rid of the name string and the timer reference, allowing those objects to be GC’ed? Or is the timer and the string still around, but now inaccessible, since I’ve eliminated the table1? I think the way GC in Lua works is that if there’s no way to reference it, then it’s GC’ed, but I always see examples of nilling the reference itself - never its “parent table” (or whatever you call that).

I suppose this question is even applicable to the following:

[lua]_G = nil – does this clear all global variables?[/lua]
[import]uid: 49372 topic_id: 9435 reply_id: 309435[/import]

Does that last line above get rid of the name string and the timer reference, allowing those objects to be GC’ed? Or is the timer and the string still around, but now inaccessible, since I’ve eliminated the table1? I think the way GC in Lua works is that if there’s no way to reference it, then it’s GC’ed, but I always see examples of nilling the reference itself - never its “parent table” (or whatever you call that).

Yeah the garbage collector cleans up all inaccessible objects. The reason you see lots of examples of “over nilling” is because there are a lot of beginner programmers using Corona and it’s easier/safer to just nil every reference rather than dissect which references actually need to be nilled and why.

I once posted a detailed explanation for someone of all the situations where the GC kicks in, I’ll see if I can find that.

As far as your last question though I have no idea. Although that makes logical sense, I suspect that Lua protects the global table. After all, you never have to explicitly create it in the first place, so being able to remove it would be weird.

ADDITION: Found it
http://developer.anscamobile.com/forum/2011/01/14/how-do-i-tell-if-my-game-leaking#comment-16568 [import]uid: 12108 topic_id: 9435 reply_id: 34600[/import]

@jhocking:

Thanks for the answer, that makes a lot of sense. Also, your explanation in the other thread was great! I’m bookmarking that one…

On another note, I wish some of those threads would make their way into the official documentation. The official docs and API will help you write an application, but it won’t be a very good one. These forums are essential but I feel like I need to read almost every thread to figure out how all this stuff actually works. [import]uid: 49372 topic_id: 9435 reply_id: 34606[/import]

The “scope” concept of Lua is probably the most difficult thing for new programmers to wrap their brains around. I’m now 8 months into Lua and I still occasionally wrestle with it.

Most recently, I needed to use a global variable that stores data required across several Lua modules. I assumed (stupidly, in retrospect) that I could just declare this variable anywhere and it would be a 100% global variable. Wrong! I had it structured like this:

-- in main.lua  
local function doWhatever()  
 globalScore = 100 --declare global variable here  
 viewCurrentScore() --call function in another Lua module  
end  
  
-- in another module, i.e. scores.lua  
function viewCurrentScore()  
 print(globalScore) --print score from global variable  
end  

I learned later that because I was declaring it within a local function in the first module, it was not truly recognized across a global application scale. Bad news indeed for my app! This “global” variable was sort of pseudo-global… not local, but also not global across the entire app, because it was nested down inside a local function and not available to all other functions.

The solution was simple, of course… I just declared this variable as a true global outside this local function, at the very top of main.lua. Then it became available to everything else, and I could set it to any desired value in any module.

This might be totally obvious to some developers, but for those newer to Lua, remember that global doesn’t always equal FULL global. Be careful when and where you declare it! Of course, ideally we should avoid global variables outright, but occasionally they’re necessary.

More details in this tutorial, for those who haven’t read it already:
http://lua-users.org/wiki/ScopeTutorial

Brent Sorrentino
Ignis Design [import]uid: 9747 topic_id: 9435 reply_id: 34625[/import]

The solution was simple, of course… I just declared this variable as a true global outside this local function, at the very top of main.lua. Then it became available to everything else, and I could set it to any desired value in any module.

That’s what I thought you needed to do – until I started having weird errors in my app. I ended up having to prefix the global vars with _G. to make them work.

So in main.lua I had:

currentScore = 0  

…and then in play.lua I had to use:

\_G.currentScore = 20  

…to make it work.

Tables that I declared in main.lua worked fine everywhere:

myData = {}  

…but not “regular” variables.

I’m too new at Lua to know why, and since _G.foo works I stopped looking for the answer. :slight_smile: But I would like to figure it out at some point.

Jay [import]uid: 9440 topic_id: 9435 reply_id: 34633[/import]

I’ve never used the “_G.” prefix for globals, but if it works, it works! :slight_smile:

Did you try declaring a normal global (without _G) in the core “main.lua”, at the very top, outside of all functions? This seems to be working for me. I actually keep a series of values in this variable as indexes, for example:

glVars = { life, score, skill }

When necessary, I either read a value using an index (local life = glVars[1]), or I assign a new value (glVars[1] = 10).

One factor I noticed is that I can’t (or shouldn’t) “re-assign” this global variable… only the values within it. It was causing problems if I executed “glVars = {}” somewhere else in my app, because that’s technically assigning a NEW table (and new core system ID) to the global variable. It seemed to be more predictable to keep the original declaration intact and simply assign/read values as needed.

One way to check your functionality is the humble “print()” statement. When you first declare your global variable, print its ID immediately after (you’ll get some reading like “table 0x81ce96”). Later, in your other modules, print out the same global variable and watch the console to see if the IDs match. If they do, that means Lua is using the exact same global variable and you’re all set to go!

If you intend to use this global variable throughout, don’t “nil” it out and then re-assign it. That again might mix up the IDs (I can’t vouch for this, but it’s possible).

Maybe a more veteran Lua programmer can weigh in on this topic. I can’t vouch 100% for the accuracy of my statements above… it’s just what I have observed through trial, error, and alot of testing.
[import]uid: 9747 topic_id: 9435 reply_id: 34638[/import]

Using global variables is bad form in programming because it frequently leads to confusion and spaghetti code. I use a few global variables in my project but wish I had instead used a singleton approach to store the shared values in a separate module:
http://developer.anscamobile.com/forum/2011/04/28/singletons-lua

I’ll probably refactor my code after releasing the first version, but I don’t want to make major changes right now. [import]uid: 12108 topic_id: 9435 reply_id: 34676[/import]

Guys,
the use of _G.globalVar = ‘something’ has much less to do with the global being declared inside of a function, and much more to do with the fact that the function lives inside of a “module”

“global” is somewhat of a misnomer in Lua. _G is simply ONE of many possible environments. If your code (or Ansca’s) use the “module()” function in any place, then there is no one “global” space. Each module() creates it’s own “global” environment but IF the module is also created with the “package.seeall” function, then it will inherit from _G even though it does not have a direct reference to vars defined in _G

clear as mud?? Read about lua “environments” :wink: [import]uid: 6175 topic_id: 9435 reply_id: 34712[/import]