Thread Tools Display Modes
09-16-11, 02:39 PM   #1
taurouset
A Deviate Faerie Dragon
 
taurouset's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 11
Setting a table equal to another table.

I have two tables: CC_Vars and CC_Defaults. Both have two tables in them: Data, and Options.

Then I have a button, that calls a function, that does this: CC_Vars.Options = CC_Defaults.Options; as well as a function that does: CC_Vars.Data = CC_Defaults.Data;

The problem is, this only works once. I've tested as much as I can think of, and no matter what I do, this only works the first time I click the button, then it won't work anymore. I've made it so the function posts a message in the chat log, so I know the function is firing.

This doesn't make any sense to me. The only thing I can think of is CC_Defaults.Options could be changing somewhere, but I've checked and checked and CC_Defaults is constant.

EDIT: I just discovered my using a /script to output the data in CC_Defaults, and it turns out it is changing. But there is nothing in my code could do that!?

EDIT2: I have a slider that changes the alpha of a frame:
Code:
<Scripts>
     <OnLoad>
          CC_SetupSlider(self, "Alpha", 0, 1, 0);
     </OnLoad>
     <OnValueChanged>
          CC_Vars.Options.alpha = self:GetValue();
          setAlpha(CC_Vars.Options.alpha);
     </OnValueChanged>
</Scripts>
the setAlpha function isn't the problem, it doens't have the word Default in it at all.
Neither does SetupSilder.

But ingame, when I move the slider, it changes CC_Defaults.Options.alpha as well.

Last edited by taurouset : 09-16-11 at 02:54 PM.
  Reply With Quote
09-16-11, 03:01 PM   #2
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Originally Posted by taurouset View Post
I have two tables: CC_Vars and CC_Defaults. Both have two tables in them: Data, and Options.

Then I have a button, that calls a function, that does this: CC_Vars.Options = CC_Defaults.Options; as well as a function that does: CC_Vars.Data = CC_Defaults.Data;

The problem is, this only works once. I've tested as much as I can think of, and no matter what I do, this only works the first time I click the button, then it won't work anymore. I've made it so the function posts a message in the chat log, so I know the function is firing.

This doesn't make any sense to me. The only thing I can think of is CC_Defaults.Options could be changing somewhere, but I've checked and checked and CC_Defaults is constant.

EDIT: I just discovered my using a /script to output the data in CC_Defaults, and it turns out it is changing. But there is nothing in my code could do that!?
I also had a similar problem .. I was thinking that, maybe instead of being "copied", both variables would just point to the same table (which is located on memory address X)

So the table of variable1 would get discarded, and you'd then instead be using the table of variable2 (defaults)

Would this work?
Code:
for k, v in pairs(CC_Defaults.Options) do
	CC_Vars.Options[k] = v
end

for k, v in pairs(CC_Defaults.Data) do
	CC_Vars.Data[k] = v
end

Last edited by Ketho : 09-16-11 at 03:07 PM.
  Reply With Quote
09-16-11, 03:16 PM   #3
taurouset
A Deviate Faerie Dragon
 
taurouset's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 11
Originally Posted by Ketho View Post
I also had a similar problem .. I was thinking that, maybe instead of being "copied", both variables would just point to the same table (which is located on memory address X)

So the table of variable1 would get discarded, and you'd then instead be using the table of variable2 (defaults)

Would this work?
Code:
for k, v in pairs(CC_Defaults.Options) do
	CC_Vars.Options[k] = v
end

for k, v in pairs(CC_Defaults.Data) do
	CC_Vars.Data[k] = v
end
Haha, that actually works! So what I had before was essentially a pointer to a table? WHY!?
  Reply With Quote
09-16-11, 03:23 PM   #4
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Originally Posted by taurouset View Post
Haha, that actually works! So what I had before was essentially a pointer to a table? WHY!?
Someone else will come by and explain it better, I think

Anyway here is some reading stuff
Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.
  Reply With Quote
09-16-11, 03:25 PM   #5
taurouset
A Deviate Faerie Dragon
 
taurouset's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 11
Originally Posted by Ketho View Post
XD I've been using my knowledge of C++ to try to code in Lua and at first it was very similar, but a few things are getting weird.
  Reply With Quote
09-16-11, 03:37 PM   #6
ALZA
A Deviate Faerie Dragon
 
ALZA's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 19
Won't it be easier to use metatables for defaults? =)

Code:
local CC_Defaults = {
	"var1" = "val1",
	"var2" = "val2",
}

CC_Vars = setmetatable(CC_Vars or {}, {__index = CC_Defaults})

--[[ testing ]]
print(CC_Vars.var1) -- outputs "val1"

CC_Vars.var1 = "changed_val1"
print(CC_Vars.var1) -- outputs "changed_val1"
print(CC_Defaults.var1) -- it's still "val1"

wipe(CC_Vars) -- we're back to defaults
  Reply With Quote
09-16-11, 10:24 PM   #7
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,326
Originally Posted by taurouset View Post
XD I've been using my knowledge of C++ to try to code in Lua and at first it was very similar, but a few things are getting weird.
An easier way to think of it is that objects such as tables, functions, userdata, and threads are stored as a pointer to the object. As such, they are always passed by reference. This differs from primitive data, like numbers, strings, and boolean values which are stored and passed by value.

A good way to keep track of pointers is to pass the object directly to print(). It'll call tostring() on it and display the pointer value. For example, if you run print() on a table, you'll get a value displayed like "table: 1A2B3C4D". Note all references to the same table will print out the same pointer ID.



Originally Posted by ALZA View Post
Won't it be easier to use metatables for defaults? =)

Code:
local CC_Defaults = {
	"var1" = "val1",
	"var2" = "val2",
}

CC_Vars = setmetatable(CC_Vars or {}, {__index = CC_Defaults})

--[[ testing ]]
print(CC_Vars.var1) -- outputs "val1"

CC_Vars.var1 = "changed_val1"
print(CC_Vars.var1) -- outputs "changed_val1"
print(CC_Defaults.var1) -- it's still "val1"

wipe(CC_Vars) -- we're back to defaults
If you're loading in CC_Vars from a SavedVariable, you'll need to reapply the metatable after ADDON_LOADED fires as the initial table is completely overwritten with a new one.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 09-16-11 at 10:39 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Setting a table equal to another table.


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off