Log In  

Sorry for the vague subject line...I don't know how to best describe what I'm seeing. That probably means this issue is certainly something I'm doing wrong but just don't know what. I swear I've done it in the past without problems so it has me wondering if it's a new P8 version thing or if I'm just crazy...anyway...

I have something like this...

pool={
   {name="Jerry"},
   {name="Tom"}
}
list={}

function mybutt(myx)
   local obj=pool[1]

   obj.x=myx
   obj.y=20

   add(list, obj)
end

mybutt(10)
mybutt(64)
mybutt(82)

And the problem is that when I loop through 'list' every value of 'x' is the last value added via the function, so in this example, 82.

But when I do rewrite as below it works as I think it should above...

pool={
   {name="Jerry"},
   {name="Tom"}
}
list={}

function mybutt(myx)
   local tmp=pool[1] -- This is the part that feels wrong

   local obj={}
   obj.name=tmp.name
   obj.x=myx
   obj.y=20

   add(list, obj)
end

mybutt(10)
mybutt(64)
mybutt(82)

It's like it won't add unique properties to the local 'obj' variable when I create it from another table. I have to put the pull from the other table (pool) into its own variable, then populate the table I actually want to add to the list.

I could swear that I've used the first version in the past and it has worked just fine...yes? No?

I shouldn't have to do it that way. Creating local from a global and then adding to that local should work just fine using dot notation and so on. It's bizarre.

And maybe I'm just all sorts of wrong, in which case, why doesn't example #1 work like I expect?

P#48435 2018-01-21 22:28 ( Edited 2018-01-22 15:31)

Assigning a table to a variable creates a pointer to the table. So in the first example, "mybutt" is just changing the values in that table instead of creating a new table each time. Making a new table and copying elements to it like you're doing in the second example is the way to go.

P#48440 2018-01-22 00:38 ( Edited 2018-01-22 05:41)

So pool is your templates, and list is your instances?

In that case, yeah, what ToyCrab said. You need to manually copy the contents of the template into each new instance.

If you speak C++, I think this is what you were expecting:

// copy constructor
auto obj = pool[1]; 

obj.x=myx;
obj.y=20;

list.push_back(obj);

But with Lua, this is what you were getting:

// pointer
auto *obj = &pool[1];

obj->x=myx;
obj->y=20;

list.push_back(obj);

Lua's deal is that tables are a data type, not a variable type. Variables can only hold numbers, booleans, or nil directly. Everything else is a reference to some kind of data, such as a string, a function, or a table. And references can be (accidentally) shared.

If you know you're not going to have nested tables, which can be more complex to copy (and dangerous in the case of self-referential tables), you can just use a simple function like this:

function copy_of(ts)
   local td={}
   for k,v in pairs(ts) do
      td[k]=v
   end
   return td
end

function mybutt(myx)
   local obj=copy_of(pool[1])

   obj.x=myx
   obj.y=20

   add(list, obj)
end
P#48443 2018-01-22 02:09 ( Edited 2018-01-22 07:24)

Ahh...last night in bed I thinking of this and also came to the idea that I was expecting Local to make a copy of the table value, not just reference it. I understand completely. I’ll maybe rethink my structures in the first place and use that dupe function if I need to. Thanks guys!

P#48451 2018-01-22 10:31 ( Edited 2018-01-22 15:31)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 18:50:20 | 0.008s | Q:17