Reply
 
Thread Tools Display Modes
Old 12-12-13, 07:36 AM   #1
Mock
A Black Drake
AddOn Author - Click to view addons
Join Date: May 2007
Posts: 83
Defining functions

Hello

I'm fiddling around with some addons and I see people are using:

Code:
GetHealthText = function(unit, cur, max)
end

and

function GetHealthText (unit, cur, max)
end

What is the difference between these 2?
Mock is offline   Reply With Quote
Old 12-12-13, 07:50 AM   #2
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 741
The most common is using "function name(args)"

Also you can use "local" as prefix to limit the scope, otherwise your examples create global functions usable by all addons, and it might even write over already existing functions like that. Just be careful.
__________________
Profile: Curse | Wowhead
Vlad is offline   Reply With Quote
Old 12-12-13, 07:56 AM   #3
Mock
A Black Drake
AddOn Author - Click to view addons
Join Date: May 2007
Posts: 83
Thanks

Yeah I've had my code do bad things to other addons

But they do the exact same thing?
Mock is offline   Reply With Quote
Old 12-12-13, 08:06 AM   #4
Vrul
A Chromatic Dragonspawn
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 192
Both of your examples would work exactly the same. The only time there would be a difference between them is if they were declared as local and were for a recursive function.
Code:
local function TestA(x)
    x = tonumber(x) or 0
    print("TestA", x)
    if x > 0 then
        TestA(x - 1)
    end
end

TestA(1)

local TestB = function(x)
    x = tonumber(x) or 0
    print("TestB", x)
    if x > 0 then
        TestB(x - 1)
    end
end

TestB(1)
In that example TestA would work fine but TestB would throw an error about trying to call a global TestB that is nil. The reason TestB throws an error is that the right side of the = is processed first so the function is created before the local variable it will be saved to. To make TestB work like TestA and still be local you would have to do:
Code:
local TestB
TestB = function(x)
    x = tonumber(x) or 0
    print("TestB", x)
    if x > 0 then
        TestB(x - 1)
    end
end

TestB(1)
Vrul is offline   Reply With Quote
Old 12-12-13, 08:11 AM   #5
MoonWitch
A Rage Talon Dragon Guard
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 342
Everyone beat me to the punch

Last edited by MoonWitch : 12-12-13 at 08:13 AM.
MoonWitch is offline   Reply With Quote
Old 12-12-13, 08:16 AM   #6
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 741
Also when using a local function you can play with the variables and store them in unusual ways.

Like for instance this snippet. I've used similar to alter the default UnitName returned values to always include the realm, instead of nil when the unit is on the same realm as you. Note this is old code and with recent realm changes it might not work as expected.
Code:
local UnitName
do
  local _G, name, realm = _G -- the _G assignment is often frowned upon or looked at as redundant

  function UnitName(...)
    name, realm = _G.UnitName(...)
    if not realm then
      realm = GetRealmName()
    end
    return name, realm
  end
end

print(UnitName("target")) -- if the target is on your realm it actually returns the name instead of nil
The pro with doing it like this is that name and realm are local yet not in the whole scope of the addon code. And since it reuses the same storage area for both name and realm between the function calls it just feels nice.

I doubt you'd notice much performance improvement between this version and simply using "local name, realm = _G.UnitName(...)" - maybe if your testing scope is large enough you might notice some time differences.
__________________
Profile: Curse | Wowhead
Vlad is offline   Reply With Quote
Old 12-12-13, 08:23 AM   #7
Mock
A Black Drake
AddOn Author - Click to view addons
Join Date: May 2007
Posts: 83
Alright, thanks for explaining so thoroughly.

I got confused when these 2 methods were mixed in the same addon, guess it's because they've copied bits and pieces from other places.
Mock is offline   Reply With Quote
Old 12-12-13, 08:30 AM   #8
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 741
There are several other ways you declare a function, so if you experience issues when coding your own do come back and ask.
__________________
Profile: Curse | Wowhead
Vlad is offline   Reply With Quote
Old 12-12-13, 08:47 AM   #9
Mock
A Black Drake
AddOn Author - Click to view addons
Join Date: May 2007
Posts: 83
Will do, you've been very helpful.
Mock is offline   Reply With Quote
Old 12-12-13, 05:42 PM   #10
Phanx
A Pyroguard Emberseer
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 3,684
Originally Posted by Vlad View Post
local _G, name, realm = _G -- the _G assignment is often frowned upon or looked at as redundant
name, realm = _G.UnitName(...)
>_<

Yes, the _G upvalue there is redundant and useless clutter, unless you are looking up globals you are constructing dynamically (eg _G["PartyFrame"..i.."HealthBar"]). In your example, you would be better off just upvaluing UnitName directly, or not bothering to upvalue at all (unless you're running that code inside an OnUpdate script or CLEU handler or something similarly spammy).
__________________
Author/maintainer of Grid, PhanxChat, ShieldsUp, and many more.
Troubleshoot an addonTurn any code into an addonMore addon resources
Need help with your code? Post all of your actual code! Attach or paste your files.
Please don’t PM me about addon bugs or code questions. Post a comment or forum thread instead!
Phanx is offline   Reply With Quote
Old 12-16-13, 07:35 AM   #11
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 741
Originally Posted by Phanx View Post
>_<

Yes, the _G upvalue there is redundant and useless clutter, unless you are looking up globals you are constructing dynamically (eg _G["PartyFrame"..i.."HealthBar"]). In your example, you would be better off just upvaluing UnitName directly, or not bothering to upvalue at all (unless you're running that code inside an OnUpdate script or CLEU handler or something similarly spammy).
Yeah I should just have upvalued UnitName directly. Was tired when I wrote the example. :P
__________________
Profile: Curse | Wowhead
Vlad is offline   Reply With Quote
Reply

Go BackWoWInterface » Developer Discussions » Lua/XML Help » Defining functions

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