WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Defining functions (https://www.wowinterface.com/forums/showthread.php?t=48658)

Mock 12-12-13 08:36 AM

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?

Vlad 12-12-13 08:50 AM

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. :)

Mock 12-12-13 08:56 AM

Thanks

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

But they do the exact same thing?

Vrul 12-12-13 09:06 AM

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)


MoonWitch 12-12-13 09:11 AM

Everyone beat me to the punch ;)

Vlad 12-12-13 09:16 AM

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. :)

Mock 12-12-13 09:23 AM

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.

Vlad 12-12-13 09:30 AM

There are several other ways you declare a function, so if you experience issues when coding your own do come back and ask.

Mock 12-12-13 09:47 AM

Will do, you've been very helpful.

Phanx 12-12-13 06:42 PM

Quote:

Originally Posted by Vlad (Post 288087)
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).

Vlad 12-16-13 08:35 AM

Quote:

Originally Posted by Phanx (Post 288124)
>_<

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


All times are GMT -6. The time now is 03:54 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI