User:Egingell/Fix deprecated variables
Fixing addons after the removal of the magic global variables this and argX and replacing the removed getglobal function.
Details
As you may know, these variables and function have been removed as of patch 4.0.1. Here are some details on how to fix your addon (or someone else's).
Errors Messages
1. There will be an error message to the effect of "Attempt to reference global variable "this" a nil value" or "Attempt to call global function "getglobal" a nil value." These errors will come with line numbers; as with the error, "[AddOn\Addon.lua:59] Attempt to call global function "getglobal" a nil value," which is directing you to line 59 of the file "AddOn\Addon.lua").
2. If your addon doesn't throw errors, then you don't need this.
3. Just because you get only one error, doesn't mean you only have one line to fix. Conversely, 900 errors doesn't necessarily mean there are 900 lines to fix.
4. Just because you don't get any error messages, doesn't necessarily mean you don't need to fix it.
getglobal
There are two ways to approach this fix:
1. Create a local function named getglobal and return the entry from the _G table.
local function getglobal(var) return _G[var] end
2. Replace all instances of getglobal("var name") with _G["var name"].
- Note: getglobal is defined by Blizzard in the file FrameXML/UIParent.lua, so there's no need to fix it; however, it's more efficient to use the _G table directly than call a function that does the same thing.
this
There are numerous renditions of this variable:
1. Look in any XML files for the <Scripts>...</Scripts> section (there may be many).
1a. If the script in question looks like this ("Before"), alter it to look like it does in "After" and find the matching function header in the Lua file adding "this" as the first parameter.
Before
<Scripts> <OnLoad> FunctionName() </OnLoad> </Scripts>
After
<Scripts> <OnLoad> FunctionName(self) </OnLoad> </Scripts>
1b. If it looks like this, then you don't need to do anything in the XML file.
<Scripts> <OnLoad function="FunctionName" /> </Scripts>
2. Look in any Lua files for functions that use this in them and add it to the functions parameter list. There are various other ways to do it, but this is the simplest and easiest to explain.
Before
function FunctionName() this:MethodName() this.MemberName = "stuff" end
After
function FunctionName(this) this:MethodName() this.MemberName = "stuff" end
3. If the XML contains this, change them to self.
Before
<Scripts> <OnLoad> this:FunctionName() </OnLoad> </Scripts>
After
<Scripts> <OnLoad> self:FunctionName() </OnLoad> </Scripts>
argX
This is a pain in the butt because not all argX variables were removed, just the global ones (nice, huh?).
1. Look in any XML files for references to argX (arg1, arg2, etc.) and replace them all with the appropriate variable name. To find out what that variable name is, this article lists many of them. For example, OnClick uses button and down (arg1 and arg2 respectively).
2. OnEvent now uses local argX variables as opposed to previously using the globals, so there's no need to change them other than following the steps below.
3. Follow the steps in the #this section to fix stray argX variables. These parameters must come after this or event, if applicable, as in the following example.
In the XML - Before
<Scripts> <OnClick> FunctionName(self, arg1, arg2) </OnClick> </Scripts>
After
<Scripts> <OnClick> FunctionName(self, button, down) </OnClick> </Scripts>
If not an OnEvent handler
function FunctionName(this, arg1, arg2, arg3, arg4, _, arg6) -- one for every one needed in sequence including ''_'' for unused ones. this:MethodName(arg2, arg3, arg4, arg6) this.MemberName = arg1 end
If an OnEvent handler
function FunctionName(this, event, arg1, arg2, arg3, arg4, _, arg6) -- one for every one needed in sequence including ''_'' for unused ones. if event == "EVENT" then this:MethodName(arg2, arg3, arg4, arg6) this.MemberName = arg1 end end
Other things you can do
varargs
varargs are a construct that makes a list of values in the order they were passed to a function. You can change every function header in your Lua files (or XML files if you declared functions in them) to use the vararg expression.
If not an OnEvent handler
function FunctionName(...) local this, arg1, arg2, arg3, arg4, _, arg6 = ... this:MethodName(arg2, arg3, arg4, arg6) this.MemberName = arg1 end
If an OnEvent handler
function FunctionName(...) local this, event, arg1, arg2, arg3, arg4, _, arg6 = ... if event == "EVENT" then this:MethodName(arg2, arg3, arg4, arg6) this.MemberName = arg1 end end
However, it is common practice and good form to only use vararg for argX. Like the following.
If not an OnEvent handler
function FunctionName(this, ...) local arg1, arg2, arg3, arg4, _, arg6 = ... this:MethodName(arg2, arg3, arg4, arg6) this.MemberName = arg1 end
If an OnEvent handler
function FunctionName(this, event, ...) local arg1, arg2, arg3, arg4, _, arg6 = ... if event == "EVENT" then this:MethodName(arg2, arg3, arg4, arg6) this.MemberName = arg1 end end