Thread Tools Display Modes
03/23/14, 09:14 PM   #1
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Lua, ESO, or me?

Issue I am trying to wrap my head around:

I have a global variable for a string spacer, spacer = " | ", however, when I view details in Zgoo ESO seems to only be recognizing this as spacer = " ". Is it because it is the pipe character and I need to use something else, or is there something being lost between my file and ESO's interpreter?
  Reply With Quote
03/23/14, 09:47 PM   #2
Yssaril
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 2
Originally Posted by skyraker View Post
Issue I am trying to wrap my head around:

I have a global variable for a string spacer, spacer = " | ", however, when I view details in Zgoo ESO seems to only be recognizing this as spacer = " ". Is it because it is the pipe character and I need to use something else, or is there something being lost between my file and ESO's interpreter?
Make sure your using very unique global variables otherwise other addons or even the default UI may malfunction. Something like "addonname_spacer" usually works

Its usually best to stay away from creating globals. Less risk of other addons messing with yours and faster variable access
  Reply With Quote
03/23/14, 10:07 PM   #3
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
In addition to Yss's advice on creating globals (especially generically names ones), you may need to escape the pipe character. I don't recall correctly off the top of my head though. Try using " || " instead...
  Reply With Quote
03/23/14, 10:39 PM   #4
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Yeah, looking like it was my use of the pipe. Using a dash worked.

I completely understand refraining from using globals, however as my addon stands right now it needs to access the same variable from multiple spots. I'm going to look on my next iteration about getting rid of that though.
  Reply With Quote
03/24/14, 10:27 AM   #5
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Originally Posted by skyraker View Post
Yeah, looking like it was my use of the pipe. Using a dash worked.

I completely understand refraining from using globals, however as my addon stands right now it needs to access the same variable from multiple spots. I'm going to look on my next iteration about getting rid of that though.
I keep thinking about this and I still have no idea how to get those globals away. I only want the data that makes sense to update every frame, while keeping event items separate. If I remove the globals, I feel that I would need to update everything every frame. While in the grand scheme of the addon it probably isn't taking much processing to do so, trading off one bad practice for another doesn't make any sense.

For example, my toolbar updates every frame by looping through the addons saved variables and only displaying those portions that are currently selected (true). Variables that update quickly (such as position) are called only if that is one of the selected portions and is called from the function that builds the bar. For everything else, the only time the string associated with those portions of the toolbar is changed is when its associated event fires.
  Reply With Quote
03/24/14, 01:37 PM   #6
Vuelhering
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 169
Originally Posted by Yssaril View Post
Its usually best to stay away from creating globals. Less risk of other addons messing with yours and faster variable access
Is there a way to scope a variable to only your addon (across several Lua files) without making it global?

Something like...

file1:
local X=555
setup-file2(&X)
X = 444
print X => 444

file2:
local X
function setup-file2(&Y)
X = &Y
end
print X => 444 --after setting it in file1


I don't remember there being any way to equivalence two differently-scoped variables like that in Lua without doing something like a function. But calling a function would probably be slower than using a global.

Last edited by Vuelhering : 03/24/14 at 01:47 PM.
  Reply With Quote
03/24/14, 02:27 PM   #7
Halja
 
Halja's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 111
Variable scope is always a fun question. I may have this wrong but here I go.
Game Global (G_) is a lua table and global to all
Ad-on's SavedVariable is lua table inside G_ and is global to all your add-on files.
lua file
var1 = "something" --is available to all files in the add-on
local var2 = "something" -- is scoped to the file only
local function
local var1 = "something" -- is scoped to the function call only
lua Class

local var1 = "something" -- is scoped to every thing in the class
local function
local var1 = "something" -- is scoped to the function call only



The 'include' part is the <ad-on>.txt file. I have not played with Bindings type files. So, I can not speak to the scope of those.
--halja
  Reply With Quote
03/24/14, 03:01 PM   #8
Xrystal
caritas omnia vincit
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 369
I believe the first var1 is classed as global across all addons and is the same as adding it to the _G table.

I am not sure if ESO has the equivalent of the addon wide data table but that would be the only way to be addon wide across all files for just a single addon.



Lua Code:
  1. globalVar = "All Addons can see me"
  2.  
  3. local localVar = "This file can see me"
  4.  
  5. function globalFunc = All addons can use me
  6. global globalFunc = function() ... same as above
  7.  
  8. local function localFunc = Only this file can use me
  9. local localFunc = function() .. same as above

Lua Code:
  1. local function aFunc()
  2.    local localVar = "Only this function has access to me"
  3.    return localVar  ... unless I return it so that they can use it
  4. end

Lua Code:
  1. for I = 1,10 do
  2.    local localVar1  = "available to the whole for loop"
  3.    if I == 4 then
  4.       local localVar2 = "available only to the if block"
  5.    end
  6. end

Hope these and the other comments help you understand how scope works.

Last edited by Xrystal : 03/24/14 at 03:03 PM.
  Reply With Quote
03/24/14, 03:24 PM   #9
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Originally Posted by Xrystal View Post
I believe the first var1 is classed as global across all addons and is the same as adding it to the _G table.
Correct.
Originally Posted by Xrystal View Post
I am not sure if ESO has the equivalent of the addon wide data table but that would be the only way to be addon wide across all files for just a single addon.
No, it does not.

Local variables are available at the scope they are defined and lower. Global variables are available to all things - hence being called "global". If you use a global variable called spacer, and I accidentally leak a global variable also called spacer, whichever one was defined last will overwrite the other.

If you want variables accessible throughout your entire addon, across multiple files, then use a table to store them in. Here is just one example of how you can do that.

File1.lua
Lua Code:
  1. MyAddonTable = {}   --define your table
  2. local MyAddonTable = MyAddonTable   --go ahead and give it a local reference, too, for this file
  3. MyAddonTable.var = "varForAllFiles"

File2.lua
Lua Code:
  1. --since File1 loaded first, MyAddonTable has already been created
  2. local var = MyAddonTable.var   --we can copy the value of MyAddonTable.var to a local variable
  Reply With Quote
03/24/14, 04:00 PM   #10
Vuelhering
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 169
Originally Posted by Seerah View Post
If you want variables accessible throughout your entire addon, across multiple files, then use a table to store them in. Here is just one example of how you can do that.

File1.lua
Lua Code:
  1. MyAddonTable = {}   --define your table
  2. local MyAddonTable = MyAddonTable   --go ahead and give it a local reference, too, for this file
  3. MyAddonTable.var = "varForAllFiles"

File2.lua
Lua Code:
  1. --since File1 loaded first, MyAddonTable has already been created
  2. local var = MyAddonTable.var   --we can copy the value of MyAddonTable.var to a local variable
Right. That's how I'm currently doing it to prevent issues with globals, but that table is still a global. And other addons can still potentially mess things up. It's far less likely, but they still can.

Although the "local var = MyAddonTable.var" is not two-way. If you change the value of var, you still have to export it back out to MyAddonTable.var.
  Reply With Quote
03/24/14, 04:15 PM   #11
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
Thanks you for all the replies so far. Scope is always a fun topic.

1) Like all the talk about using spacer as a global, but my addon didn't call it simply that. Looking at things, I managed to completely rid it as a global though.

2) If a global in the lua file is available to all addons, and making it a local outside the scope of any function makes it only available to the addon, then I may have my problem solved in a sense without much of a change. When I was thinking of it as a global, I was thinking only that it was global to the addon. If that is more 'acceptable', then maybe it is best to keep things that way (but just in case ensure all my variables aren't easily reproducible by other addons).
  Reply With Quote
03/24/14, 04:23 PM   #12
Halja
 
Halja's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 111
So instead of a Cross-Site scripting attack, there could be a cross add-on scripting attack vector on a lua table...
A silly thing to do but Mojo Jojo would be proud.
  Reply With Quote
03/24/14, 04:36 PM   #13
Xrystal
caritas omnia vincit
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 369
Originally Posted by skyraker View Post
Thanks you for all the replies so far. Scope is always a fun topic.

1) Like all the talk about using spacer as a global, but my addon didn't call it simply that. Looking at things, I managed to completely rid it as a global though.

2) If a global in the lua file is available to all addons, and making it a local outside the scope of any function makes it only available to the addon, then I may have my problem solved in a sense without much of a change. When I was thinking of it as a global, I was thinking only that it was global to the addon. If that is more 'acceptable', then maybe it is best to keep things that way (but just in case ensure all my variables aren't easily reproducible by other addons).

Nah, it's still global, you just have a local reference.

MyUniqueAddonName_LastQuestID = 1 ... This is a global variable
local lastQuestID = MyUniqueAddonName ... this gives you a local version of the variable

As far as I know this would either branch, so to speak, the variable so that now there is a global version and a local version. Whether they co-exist or not I don't know. I think I have read both sides of that conversation and still aren't sure of when allocation is just a reference or whether it is another copy of the variable. Possibly functions and tables are referenced and others are just plain values
  Reply With Quote
03/24/14, 05:48 PM   #14
skyraker
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 154
But what I am getting at is using the local reference name in both my files rather than the global name.

Code:
MS = {}
local thisMS = MS
thisMS.count = 0
Then my other file can use:

Code:
thisMS.count = thisMS.count + 1
Would that be valid?
  Reply With Quote
03/24/14, 06:11 PM   #15
Xrystal
caritas omnia vincit
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 369
Yes that would work as MS = {} is a global table available to all addons, but each file would only be able to access the MS one, so you would have to add that local line in each file if you want to reference it in the same way.


File 1:
-- Create or use the existing table
UniqueName_MS = UniqueName_MS or {}

-- Create a local reference to the table
local thisMS = UniqueName_MS


File 2:
-- Create or use the existing table
UniqueName_MS = UniqueName_MS or {}

-- Create a local reference to the table
local thisMS = UniqueName_MS


Something like this near the top of your files will simulate an addon wide variable but it is in essence a global variable for all addons to access, so bear that in mind.
  Reply With Quote
03/24/14, 09:14 PM   #16
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Originally Posted by Vuelhering View Post
Right. That's how I'm currently doing it to prevent issues with globals, but that table is still a global. And other addons can still potentially mess things up. It's far less likely, but they still can.
But it's just one global. And your global table should have a unique name, not a generic one. If someone still wants to come around and mess with your table because it's global, you have bigger problems.

Originally Posted by Vuelhering View Post
Although the "local var = MyAddonTable.var" is not two-way. If you change the value of var, you still have to export it back out to MyAddonTable.var.
Obviously you would use MyAddonTable.var to write to the table and only use var as a local reference to the value that was in the table instead of doing the global and table lookups. Writing to a variable is done less often that reading a variable, no?
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Lua, ESO, or me?

Thread Tools
Display Modes

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