Copy/clone without reference to original object

I have a table containing display objects. I need to copy this table to another table and then empty the original table. The problem seems to be that when I empty the original table, the values in the “new” table disappear as well. Here is the code:

local newTable = {}
function copyTable(oldTable)
    newTable = {}
    for i = 1, #oldTable do
        if (oldTable[i].myType ~= nil) then
            newTable[#newTable + 1] = oldTable[i]
        end
    end

    for i = 1, #oldTable do
        oldTable[i]:removeSelf()
        oldTable[i] = nil
    end
end

I have tried to “deep copy” the table (e.g. http://lua-users.org/wiki/CopyTable) but the values in the “new” table still disappear.

Any ideas?

Hi.

Are you reusing the old tables? If not, you could just nil the table itself, e.g.

my\_table = nil 

in the code outside this function, instead of per-element.

If you are reusing them, it sounds like you have multiple tables? One of my guesses, then, is how you have newTable as an upvalue, rather than a local / return value, so it’s going to be getting overwritten each time you call your copy function; unless it’s assigned to something else before the next call, it will get lost.

Also, you’re copying the reference to the display object, not making a new instance with all its properties, so you don’t want that removeSelf () in there at all.

@StarCrunch:

Thanks for your reply.

The reason I am emptying the table per element and by removeSelf() and nil is that I want to make sure that the objects in the table do not take memory. If I just set the table to nil, won’t the elements in the table still be considered as being used by the garbage collector?

Well, I assume, since it’s a copy, that you don’t want to destroy the display objects. Furthermore, I’m guessing that you figure you’ll end up with 2 copies of each display object, but are instead getting 0.

The thing is, you’re only copying over a reference to the object, not the object itself. A reference is very lightweight. When you do removeSelf (), you remove the common object, so from either point of view it’s dead.

You say the values disappear… are they nil , or are you getting crashes from dead objects? The latter would be explained by what I bring up.

If not that… are you sure your elements all have myType?

If you’re going to reuse the table, then nil’ing out each element makes perfect sense. If you’re just going to throw the table away, it isn’t necessary to do all the per-element stuff, since the equivalent will happen anyhow. That said, it’s harmless and usually cheap enough to do so; it was just an observation, really. (You do need to manually wipe out any Corona-controlled resources, of course, for instance if you really did want to destroy display objects.)

That’s just it: I was hoping to make a copy of the object itself, not just of the reference to it. But then, how would I go about to make a copy of the object?

The oldTable contains display objects that I want to destroy altogether, in which case I understand that you say that I need to wipe them on a per element basis.

Thanks again for your answer!

Hi.

Are you reusing the old tables? If not, you could just nil the table itself, e.g.

my\_table = nil 

in the code outside this function, instead of per-element.

If you are reusing them, it sounds like you have multiple tables? One of my guesses, then, is how you have newTable as an upvalue, rather than a local / return value, so it’s going to be getting overwritten each time you call your copy function; unless it’s assigned to something else before the next call, it will get lost.

Also, you’re copying the reference to the display object, not making a new instance with all its properties, so you don’t want that removeSelf () in there at all.

@StarCrunch:

Thanks for your reply.

The reason I am emptying the table per element and by removeSelf() and nil is that I want to make sure that the objects in the table do not take memory. If I just set the table to nil, won’t the elements in the table still be considered as being used by the garbage collector?

Well, I assume, since it’s a copy, that you don’t want to destroy the display objects. Furthermore, I’m guessing that you figure you’ll end up with 2 copies of each display object, but are instead getting 0.

The thing is, you’re only copying over a reference to the object, not the object itself. A reference is very lightweight. When you do removeSelf (), you remove the common object, so from either point of view it’s dead.

You say the values disappear… are they nil , or are you getting crashes from dead objects? The latter would be explained by what I bring up.

If not that… are you sure your elements all have myType?

If you’re going to reuse the table, then nil’ing out each element makes perfect sense. If you’re just going to throw the table away, it isn’t necessary to do all the per-element stuff, since the equivalent will happen anyhow. That said, it’s harmless and usually cheap enough to do so; it was just an observation, really. (You do need to manually wipe out any Corona-controlled resources, of course, for instance if you really did want to destroy display objects.)

That’s just it: I was hoping to make a copy of the object itself, not just of the reference to it. But then, how would I go about to make a copy of the object?

The oldTable contains display objects that I want to destroy altogether, in which case I understand that you say that I need to wipe them on a per element basis.

Thanks again for your answer!