How are display objects passed?

Are display objects passed by reference? In Lua, tables are passed by reference, but when I do something like this in a function:

[lua]

function removeObject(obj)

    obj:removeSelf()

    obj = nil

end

[/lua]

The display object that was passed in is not set to nil.

Thank you for clarification!!

Hi @reallyrottens_98,

Do you have the object “obj” forward-declared (upvalue) somewhere above and outside of that function? Where do you initially create it? Much of that depends on how Lua will recognize it within the “removeObject()” function you’ve written.

Best regards,

Brent

Hi Brent,

No, obj only exists in this function. If passed by reference though, shouldn’t obj just be a pointer to a memory location?

Thank you,

Ed

There’s an unfortunate collision of terminology here, since both reference and value have Lua-specific meanings as well as the more general computer science ones.

Lua :

Lua tables are references to the underlying table contents. When assigned to multiple variables, each one will contain the same value , the value being that particular reference. You can modify the table’s contents, of course, e.g. t.x = 5 , and since each such variable is currently watching the same reference, they will all see the change. If you assign a new value to one of the variables themselves, however–not its contents–the other variables still see the old table.

General :

That said, every call in Lua is actually pass-by- value. When your removeObject () function gets called, the value (your table reference) is copied into a new variable, obj. When you reassign obj, as mentioned above, you’re only changing the value held by the local variable (parameters are just this, in the end). This is true for any input.

(If by any chance you come from a C / C++ background, as your last comment suggests, a table parameter corresponds to a pointer-to-a-table, but not a pointer-to-a-pointer-to-a-table. Alternatively, it isn’t a  ref  or inout  parameter, as found in say C#.)

Exactly as per StarCrunch, just adding yet-another restatement in Lua terms::   obj is the “value-of-a-reference” not a “reference-to-a-reference” (cuz if it were you’d expect to need a double -dereference to access removeSelf – get it?  maybe something weird like [obj].removeSelf() or such, but that’s just fictional syntax, Lua doesn’t support it)

[EDIT:  i had posted a possible approach, but then deleted it cuz it needed too much “other stuff” to illustrate the one key concept, and I had surely typo’d at least once, so i deleted cuz it would probably confuse rather than clarify - suggest you just ignore if you received it via notification]

here ya go fwiw, working code instead of ottomh rambling errors :D.

the basic idea is that if you put your objects in some sort of “container” and give them a reference to that container, then they can “nil themselves” out of their container.  (most of this is just “setup” and “test” code, so just read for the key concept)

local objectList = {} -- verify display is empty print("#objects before = " .. display.getCurrentStage().numChildren .. " (should be 0)") -- create some objects for i=1,10 do -- "tempObject" is local to this block and will vanish after loop local tempObject = display.newRect(math.random(100),math.random(100),math.random(10),math.random(10)) -- its "permanent" home will be inside objectList tempObject.container = objectList objectList[tempObject] = tempObject end -- verify display is populated print("#objects after = " .. display.getCurrentStage().numChildren .. " (should be 10)") -- later, delete some objects for k,v in pairs(objectList) do local tempObject = k -- just an alias to reinforce "who" this reference "is" tempObject:removeSelf() -- -- the code of interest: -- tempObject is self-sufficiently-capable of removing itself from its container -- (that is, no direct reference to "objectList" is required) tempObject.container[tempObject] = nil end -- verify display is empty again print("#objects final = " .. display.getCurrentStage().numChildren .. " (should be 0)") -- verify objectList was also emptied for k,v in pairs(objectList) do print("THIS SHOULD NOT PRINT BECAUSE LIST IS SUPPOSED TO BE EMPTY",k,v) end print("DONE")

hth

My 2-cents.

The core of the issue here is you’re using removeSelf() on a removed object.  

I encourage people to never call removeSelf().  Use display.remove() instead:

obj:removeSelf() -- Unsafe. Will crash if obj was already removed. display.remove( obj ) -- Safe, will NEVER crash

ed: it’s good advice regardless, though i don’t think that’s what was giving him his problem (he was just wondering why his outer-scoped variable was not being nil’ed)

>>Safe, will NEVER crash

NEVER in all-caps is a pretty long time!  :)  Here’s some deliberate abuse to help shorten the wait…  :D

local obj = display.newRect(10,10,10,10) function obj:removeSelf() self:removeSelf() end display.remove(obj)

Many, many great responses, thank you!! Question answered and then some!

Corona has a great community of which I feel fortunate to be a member!

Ed

Hi @reallyrottens_98,

Do you have the object “obj” forward-declared (upvalue) somewhere above and outside of that function? Where do you initially create it? Much of that depends on how Lua will recognize it within the “removeObject()” function you’ve written.

Best regards,

Brent

Hi Brent,

No, obj only exists in this function. If passed by reference though, shouldn’t obj just be a pointer to a memory location?

Thank you,

Ed

There’s an unfortunate collision of terminology here, since both reference and value have Lua-specific meanings as well as the more general computer science ones.

Lua :

Lua tables are references to the underlying table contents. When assigned to multiple variables, each one will contain the same value , the value being that particular reference. You can modify the table’s contents, of course, e.g. t.x = 5 , and since each such variable is currently watching the same reference, they will all see the change. If you assign a new value to one of the variables themselves, however–not its contents–the other variables still see the old table.

General :

That said, every call in Lua is actually pass-by- value. When your removeObject () function gets called, the value (your table reference) is copied into a new variable, obj. When you reassign obj, as mentioned above, you’re only changing the value held by the local variable (parameters are just this, in the end). This is true for any input.

(If by any chance you come from a C / C++ background, as your last comment suggests, a table parameter corresponds to a pointer-to-a-table, but not a pointer-to-a-pointer-to-a-table. Alternatively, it isn’t a  ref  or inout  parameter, as found in say C#.)

Exactly as per StarCrunch, just adding yet-another restatement in Lua terms::   obj is the “value-of-a-reference” not a “reference-to-a-reference” (cuz if it were you’d expect to need a double -dereference to access removeSelf – get it?  maybe something weird like [obj].removeSelf() or such, but that’s just fictional syntax, Lua doesn’t support it)

[EDIT:  i had posted a possible approach, but then deleted it cuz it needed too much “other stuff” to illustrate the one key concept, and I had surely typo’d at least once, so i deleted cuz it would probably confuse rather than clarify - suggest you just ignore if you received it via notification]

here ya go fwiw, working code instead of ottomh rambling errors :D.

the basic idea is that if you put your objects in some sort of “container” and give them a reference to that container, then they can “nil themselves” out of their container.  (most of this is just “setup” and “test” code, so just read for the key concept)

local objectList = {} -- verify display is empty print("#objects before = " .. display.getCurrentStage().numChildren .. " (should be 0)") -- create some objects for i=1,10 do -- "tempObject" is local to this block and will vanish after loop local tempObject = display.newRect(math.random(100),math.random(100),math.random(10),math.random(10)) -- its "permanent" home will be inside objectList tempObject.container = objectList objectList[tempObject] = tempObject end -- verify display is populated print("#objects after = " .. display.getCurrentStage().numChildren .. " (should be 10)") -- later, delete some objects for k,v in pairs(objectList) do local tempObject = k -- just an alias to reinforce "who" this reference "is" tempObject:removeSelf() -- -- the code of interest: -- tempObject is self-sufficiently-capable of removing itself from its container -- (that is, no direct reference to "objectList" is required) tempObject.container[tempObject] = nil end -- verify display is empty again print("#objects final = " .. display.getCurrentStage().numChildren .. " (should be 0)") -- verify objectList was also emptied for k,v in pairs(objectList) do print("THIS SHOULD NOT PRINT BECAUSE LIST IS SUPPOSED TO BE EMPTY",k,v) end print("DONE")

hth

My 2-cents.

The core of the issue here is you’re using removeSelf() on a removed object.  

I encourage people to never call removeSelf().  Use display.remove() instead:

obj:removeSelf() -- Unsafe. Will crash if obj was already removed. display.remove( obj ) -- Safe, will NEVER crash

ed: it’s good advice regardless, though i don’t think that’s what was giving him his problem (he was just wondering why his outer-scoped variable was not being nil’ed)

>>Safe, will NEVER crash

NEVER in all-caps is a pretty long time!  :)  Here’s some deliberate abuse to help shorten the wait…  :D

local obj = display.newRect(10,10,10,10) function obj:removeSelf() self:removeSelf() end display.remove(obj)

Many, many great responses, thank you!! Question answered and then some!

Corona has a great community of which I feel fortunate to be a member!

Ed