Are these global variables? I'm trying to not "leak globals".
If I do like this
local currentProfile;
local profile = currentProfile;
function Tattoo:OnInitialize()
self.db = LibStub("AceDB-3.0"):New("TattooDB", defaults, "Default")
db = self.db.profile
self:RegisterChatCommand("rl", "RELOAD1")
self:RegisterChatCommand("heal", "HEAL")
self:RegisterChatCommand("dps", "DPS")
self:RegisterChatCommand("tank", "TANK")
self.db.RegisterCallback(self, "OnProfileChanged", "UpdateDisplay")
self.db.RegisterCallback(self, "OnProfileCopied", "UpdateDisplay")
self.db.RegisterCallback(self, "OnProfileReset", "UpdateDisplay")
if LibStub:GetLibrary("LibAboutPanel", true) then
self.optionsFrame = LibStub:GetLibrary("LibAboutPanel").new(nil, "Tattoo")
else
self:Print("About Panel not loaded.")
end
LibStub("AceConfig-3.0"):RegisterOptionsTable("Tattoo Heal Set", healset)
LibStub("AceConfig-3.0"):RegisterOptionsTable("Tattoo DPS Set", dpsset)
LibStub("AceConfig-3.0"):RegisterOptionsTable("Tattoo Tank Set", tankset)
LibStub("AceConfig-3.0"):RegisterOptionsTable("Tattoo Profiles", LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db))
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Tattoo Heal Set", "HealSet", "Tattoo")
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Tattoo DPS Set", "DPSSet", "Tattoo")
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Tattoo Tank Set", "TankSet", "Tattoo")
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("Tattoo Profiles", "Profiles", "Tattoo")
currentProfile = self.db:GetCurrentProfile();
end
Have I leaked any globals here?
And one more:
function Tattoo:SetTbgColor(r,g,b,a)
if r then
Tattoo.db.profile.tankbgcolor.r, Tattoo.db.profile.tankbgcolor.g, Tattoo.db.profile.tankbgcolor.b, Tattoo.db.profile.tankbgcolor.a = r,g,b,a
else
r,g,b,a = Tattoo.db.profile.tankbgcolor.r, Tattoo.db.profile.tankbgcolor.g, Tattoo.db.profile.tankbgcolor.b, Tattoo.db.profile.tankbgcolor.a
end
Tattoo.tbgleft:SetVertexColor(r, g, b, a)
Tattoo.tbgright:SetVertexColor(r, g, b, a)
end
Well, it's my first addon, and I thought "currentProfile" was getting all the values from the WTF file. Apparently, that's incorrect or you wouldn't have asked me such a question. So I guess I'll delete it and see what happens, lol.
I was just trying to ask if declaring a variable local, at the beginning of a file, would then allow you to use it freely throughout your file, without writing "local" in front of it.
I was just trying to ask if declaring a variable local, at the beginning of a file, would then allow you to use it freely throughout your file, without writing "local" in front of it.
Yes you can.
All variables default to being global, unless declared local. Once declared local, its scope is defined from the point it is declared to the end of the enclosing block. If this is at the file level scope (i.e, imagine a big "do end" block surrounding the entire file), then it will be visible to the end of the file.
You'll even often see things like this:
local pairs = pairs
near the top of addons. Here, we're declaring a local variable called pairs, and we're assigning the global function pairs to it (since the local doesn't exist until after the statement, the right hand side refers to the global). Future accesses to the pairs() function would then be faster.
Anywhere where self is in scope, self.db.profile will give you the current profile. You don't need to explicitly call GetCurrentProfile or create a local reference.
Thanks :)
I think I have removed all the globals from my file now, but is there an easy way to check? I was referred to this page: http://www.wowace.com/addons/findglobals/
However, that page and the one it references... look scary!
For example, if I want to check my CSS or XHTML, I can just paste the page into a checker page...
FindGlobals looks amazing, but I haven't tried it so far. What I do know is that any variable you declare is local to the scope in which it is declared. Here is a couple of examples. One big one I left out is local functions.
local myVariable = {} -- this will be local to the entire file, since it is declared at the top
function MyAddon:SomeFunction()
local playerName -- this is local to SomeFunction() and cannot be used outside of this function
for index, myVariable in pairs do
-- in the case of a loop, index is local to the loop, and thus you do not need "local index" somewhere
-- also, pairs is a global. in fact, any WoW APIs can be declared locally at the top of the file
-- in this case, you would want to declare local pairs = pairs at the top before
-- you declare local myVariable = {}
end
playerName = UnitName("player") -- UnitName() is an API call, and probably should have been declared at the beginning
end
-- here is the corrected variables and function
-- GetGlobal() and SetGlobal() have been removed as of patch 4.01. replace with getfenv()
local _G = getfenv(0) -- not sure what getfenv() actually does as I've never seen it documented, but it populates _G from the global to the local
local UnitName = _G.UnitName -- notice the lack of brackets "()" this is intentional
local pairs = _G.pairs
local myVariable = {}
function MyAddon:SomeFunction()
local playerName
for i, myVariable in pairs do -- most people abbreviate index as i, as the name doesn't matter, so long as you keep track in nested loops
-- this won't actually do anything, as no data has been added to myVariable, but you get the point
end
playerName = UnitName("player")
end
I run Linux, so YMMV...I wrote a shell script called "findglobals", and put it in my home bin dir along with globals.lua (which should really be located elsewhere...) - now all I need to do is type "findglobals filename.lua" and it Just Works (TM).
if you make a new function with the same name as an old function, then the new one is used as long as it's still in scope... just like variables would do.
putting "function myaddon:functionName()" only works when you have declared "myaddon" as a table. it could be local or global, but it needs to be defined. functionName is then a function that's referenced from that table. local/global isn't really pertinent to table entries. it would actually be a syntax error to put "local" in front of "function myaddon:functionName()"
1) "/console taintLog 2"
2) Logout. Delete World of Warcraft\Logs\taintlog.log or whatever it's called.
3) Login. Use your addon a bit.
4) "/console taintLog 0" before your hard drive fills up.
5) Logout.
6) Pull the taintlog file into a text editor, search around for your addon. Delete the file when finished.
function myAddon:SomeFunction() is local to whatever your addon is actually called, IE, if your addon is called BobAndTed, the line would look like
function BobAndTed:SomeFunction()
Should you have two or more addons called BobAndTed, (!), then :SomeFunction() is local to whichever .toc file loaded it. Same goes with slash commands, but since those are harder to trace, yes, you can have more than one addon trying to do different things with the same slash command.
For slash commands, it is best to create more than one. For example, create both /bobandted and /bat. If you really run into conflicts, your users will tell you. A great example of this was the /tip command, which was for TipTac, then BigWigs added that command, and the coder for TipTac had to create /tiptac.
Gobal variables are called leaky because let's say you have a variable named playerName, but did not declare it local. How many addons do you know or use that do something with the name of the player? What if more than one addon tried to do something different with playerName? It would be a mess.
What egingell said. If you take my example, the first line should have been
local myAddon = ...,
For Ace-based addons, you don't explicitly need that table, because you have
local myAddon = LibStub("AceAddon-3.0"):NewAddon("myAddon")
Delete line 420. You already have self.db, and in this case, self refers to Tattoo. GetNumAddOns() and GetAddOnInfo() are both global and need localizing. Same with IsAddOnLoaded() and any other API.
Lines 469-474 won't return anything because you declared Tattoo as local near the top of file, which line 1 should begin with the word local.
Since this thread is discussing globals, I have a related question. When scanning for loose globals, WoW Global Finder reported that AceGUIWidgetLSMlists was loose in my code. Should this be changed to _G.AceGUIWidgetLSMlists ?
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
If I do like this
Have I leaked any globals here?
And one more:
Are r,g,b,a here local or global variables?
Will this keep currentProfile a local?
Yes. Gotta ask, however -- why do you need to know the current profile, let alone assign two variables to the same thing?
I was just trying to ask if declaring a variable local, at the beginning of a file, would then allow you to use it freely throughout your file, without writing "local" in front of it.
Yes you can.
All variables default to being global, unless declared local. Once declared local, its scope is defined from the point it is declared to the end of the enclosing block. If this is at the file level scope (i.e, imagine a big "do end" block surrounding the entire file), then it will be visible to the end of the file.
You'll even often see things like this:
near the top of addons. Here, we're declaring a local variable called pairs, and we're assigning the global function pairs to it (since the local doesn't exist until after the statement, the right hand side refers to the global). Future accesses to the pairs() function would then be faster.
I think I have removed all the globals from my file now, but is there an easy way to check? I was referred to this page: http://www.wowace.com/addons/findglobals/
However, that page and the one it references... look scary!
For example, if I want to check my CSS or XHTML, I can just paste the page into a checker page...
When you prefix with your addon name, does that not make it local?
What exactly happens if you have a function with the same name as someone else? or a slash command or global variable?
putting "function myaddon:functionName()" only works when you have declared "myaddon" as a table. it could be local or global, but it needs to be defined. functionName is then a function that's referenced from that table. local/global isn't really pertinent to table entries. it would actually be a syntax error to put "local" in front of "function myaddon:functionName()"
1) "/console taintLog 2"
2) Logout. Delete World of Warcraft\Logs\taintlog.log or whatever it's called.
3) Login. Use your addon a bit.
4) "/console taintLog 0" before your hard drive fills up.
5) Logout.
6) Pull the taintlog file into a text editor, search around for your addon. Delete the file when finished.
Only if you declared myAddon as a local above it. Lua doesn't know what addons are. It's just a table with a function as a method.
function BobAndTed:SomeFunction()
Should you have two or more addons called BobAndTed, (!), then :SomeFunction() is local to whichever .toc file loaded it. Same goes with slash commands, but since those are harder to trace, yes, you can have more than one addon trying to do different things with the same slash command.
For slash commands, it is best to create more than one. For example, create both /bobandted and /bat. If you really run into conflicts, your users will tell you. A great example of this was the /tip command, which was for TipTac, then BigWigs added that command, and the coder for TipTac had to create /tiptac.
Gobal variables are called leaky because let's say you have a variable named playerName, but did not declare it local. How many addons do you know or use that do something with the name of the player? What if more than one addon tried to do something different with playerName? It would be a mess.
local myAddon = ...,
For Ace-based addons, you don't explicitly need that table, because you have
local myAddon = LibStub("AceAddon-3.0"):NewAddon("myAddon")
http://paste.wowace.com/2748/
Thanks so much :)
Lines 469-474 won't return anything because you declared Tattoo as local near the top of file, which line 1 should begin with the word local.