Thread Tools Display Modes
01-18-14, 04:24 AM   #1
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
funcName = function(p1, p2, ...) instead of function funcName(p1, p2, ...)?

Today I saw someone doing this:
Code:
funcName = function(p1, p2, ...) end
Now I'm asking myself what is this good for? What's the difference to

Code:
function funcName(p1, p2, ...) end

Last edited by Duugu : 01-18-14 at 04:35 AM.
  Reply With Quote
01-18-14, 04:36 AM   #2
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Effectively, they are the same. The only difference would be that the former could be stored in a table.

Lua Code:
  1. local functionTable = {
  2.     ["function 1"] = function(cats, dogs, horses, ...) print (cats, dogs, horses) end,
  3.     ["function 2"] = function(rabbits, ligers, belugawhales, ...) print (rabbits, ligers, belugawhales) end
  4. }

Edit: I guess another advantage of the former would be that you could change that content of that variable, from a function to something else, if you had a need to do so.
  Reply With Quote
01-18-14, 04:52 AM   #3
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Originally Posted by Clamsoda View Post
["function 2"] = function(rabbits, ligers, belugawhales, ...) print (rabbits, ligers, belugawhales) [/highlight]
Wow. The super rare and mostly unkown ligers. ;D

Thank you sir.
  Reply With Quote
01-18-14, 05:01 AM   #4
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
There is a programmatic difference between them, this post explains it.

I personally use "func = function()" when overwriting an existing function and the latter when defining my own.

Last edited by semlar : 01-18-14 at 05:05 AM.
  Reply With Quote
01-18-14, 07:01 AM   #5
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,928
I tend to use addonTable.FunctionName = function() in my addons rather than function functionName() purely for consistency, benefit wise however I can see addonTable.FunctionName = function useful for functions you want to use throughout your addon but still be 'local' to your addon and not global.


My understanding thus far is :

local function FunctionName() --- Only accessible in the current file
local FunctionName = function() --- Only accessible in the current file

function FunctionName() --- Global to all addons that want to use it
FunctionName = function() --- Global to all addons that want to use it

addonTable.FunctionName = function() ---- Only accessible to files in your addon that have the addonName,addonTable = ... at the top of the lua files.

I am sure there are some overheads in each of these cases so I won't claim to know which is best to use, but I try not to use global functions and variables unless I want the function/variable accessible outside of the addon.
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
01-18-14, 07:38 AM   #6
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Xrystal View Post
... I try not to use global functions and variables unless I want the function/variable accessible outside of the addon.
Even if you do want something to be available outside of the addon, making each item a separate global is not ideal. Instead, create one global table -- usually, your main addon frame/table/AceAddon object/whatever -- and add all the things you want to be "global" to that table, eg.

Code:
-- Global addon object:
MyAddon = {} -- or CreateFrame, or AceAddon:New, etc.

-- Local reference to the object, so that all further references
-- to it in this file are faster local lookups, rather than slower global ones:
local MyAddon = MyAddon

-- This function name is NOT in the global namespace itself, but the function
-- can be accessed through the global "MyAddon" table.
function MyAddon:DoStuff()
     print("I'm doing stuff!")
end

-- This variable name is NOT global either, but the variable can also be accessed
-- through the global "MyAddon" table.
MyAddon.someValue = 5

-- This function name IS global, and it shouldn't be!*
function MyAddon_DoStuff()
    print("I'm a slow global. :(")
end

-- This variable name is global, and it shouldn't be!
MyAddon_SomeValue = 5
* There is only one case in which you should ever give an individual function a global name, and that is if you are assigning that function as a script handler for a template defined in XML, and the only reason to define a template in XML is if you are passing it to a secure header. So, chances are very high you will never encounter this case.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
01-18-14, 07:58 AM   #7
Duugu
Premium Member
 
Duugu's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 851
Originally Posted by semlar View Post
There is a programmatic difference between them, this post explains it.

I personally use "func = function()" when overwriting an existing function and the latter when defining my own.
Thank you.
To sumarize it: there's no advantage of
Lua Code:
  1. functionName = function() end
with declaring a function. And there's the disadvantage that a recursive call doesn't work.
  Reply With Quote
01-18-14, 08:43 AM   #8
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
Recursion can work with both variants and that is explained in the linked post.
  Reply With Quote
01-18-14, 10:45 AM   #9
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Yes, but with the "var = function" style you have to separately declare "local var" before you can define "var = function" ... why clutter up your code with silly-looking and redundant variable definitions when you can just use "local function var" instead?

Plus, if you are putting your functions in a table and calling them as methods, it's cleaner to write "function tbl:var()" than "tbl.var = function(self)".
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
01-18-14, 04:38 PM   #10
Dridzt
A Pyroguard Emberseer
 
Dridzt's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2005
Posts: 1,360
My excuse is that I do use tables / frames to hold most my functions and my editor of choice gives me a nice sorted function listing on the side.

Using the context.func = function() notation gives me a very nice navigational aid for my code where functions are 'naturally' grouped by context.
  Reply With Quote
01-18-14, 07:30 PM   #11
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Not sure what I can say to improve this thread.

In general many people like to group up functions in a class-like style. Often modules create a table that contains functions that do specific things on that table only. It's wise to organize your code and avoid global leaking - it's good practice.
__________________
Profile: Curse | Wowhead
  Reply With Quote
01-22-14, 02:39 PM   #12
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,877
Can you explain how you would access throught the global "MyAddon" table?

I'm feeling dense, I see addons that:

local _, MyAddon = ...
_G.MyAddon = MyAddon

Isn't that the same as leaving out the
local _, MyAddon = ...

and just having
MyAddon = {}

or am I missing some more magic?

-- This variable name is NOT global either, but the variable can also be accessed
-- through the global "MyAddon" table.
MyAddon.someValue = 5
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
01-22-14, 02:55 PM   #13
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Just because something is global doesn't necessarily put it in Blizzard's global table, correct?

_G is just a table in the global scope, if I understand correctly. Declaring a variable globally doesn't inherently put it into _G, that would need to be done manually.

That is my perception, could be wrong of course.

Last edited by Clamsoda : 01-22-14 at 03:02 PM.
  Reply With Quote
01-22-14, 03:00 PM   #14
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,928
Originally Posted by Fizzlemizz View Post
Can you explain how you would access throught the global "MyAddon" table?

I'm feeling dense, I see addons that:

local _, MyAddon = ...
_G.MyAddon = MyAddon

Isn't that the same as leaving out the
local _, MyAddon = ...

and just having
MyAddon = {}

or am I missing some more magic?
if they hadn't added it to the _G table then it would only be global to your addon, useful for splitting up large files. Adding it to _G table I expect would mean it is now accessible by other addons, of course it would override a value already in existence with the same name in that table.
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
01-22-14, 03:04 PM   #15
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,877
Maybe my perception is messed from having changed a ton of GetGlobal calls to _G when I started on lua so my assumtion has been that _G = global global . It would be nice and useful to be set correct.

Originally Posted by Clamsoda View Post
Just because something is global doesn't necessarily put it in Blizzard's global table, correct?
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
01-22-14, 03:14 PM   #16
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,324
Originally Posted by Fizzlemizz View Post
Maybe my perception is messed from having changed a ton of GetGlobal calls to _G when I started on lua so my assumtion has been that _G = global global . It would be nice and useful to be set correct.
Actually, _G is the same as _G._G, it's a circular reference and completely unnecessary. This also means _G.MyVar is the exact same as referencing MyVar directly as long as you don't have a local definition for the variable.



The only possible use of the _G table is to reference a global by the contents of another variable.
Lua Code:
  1. local index="SomeVar";
  2. print(_G[index]);
This will print out the contents of the global SomeVar.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
01-22-14, 03:27 PM   #17
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,877
I understand that, it's the storage of global/not global I'm trying to figure.

Is
function MyFunction()
...
end

essentially the same as
local function MyFunction()
...
end
_G.MyFunction = MyFunction()

or does the first get stored globally and the second in a seperate "container" within the global space?
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 01-22-14 at 03:31 PM.
  Reply With Quote
01-22-14, 03:28 PM   #18
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
It is also useful when concatenating two strings together to find the global object. ie,

Lua Code:
  1. for i = 1, 12 do
  2.      _G["ActionButton"..i]:DoSomething()
  3. end


@Clamsoda: Anything left global is going to be in the global namespace. _G is everything in the global namespace. You don't need to manually put it there.


As Xrystal said, the contents of the vararg (...) passed to your addon are not real globals. Their scope is limited to your addon only and all the files it contains. If an author chooses to add their addon table to _G, then it is accessible to any addon as it is in the global namespace at that point.

@Fizzlemizz: The getglobal() function was just a wrapper to look something up in the _G table.
Lua Code:
  1. function getglobal(thing)
  2.      return _G[thing]
  3. end
Because it was just this thin wrapper, it was deprecated and (eventually) removed from the API. A table lookup is cheaper than a function call (especially one that just does that table lookup).


Lastly, as SDPhantom pointed out, doing _G.MyVar is pointless, as you can just reference MyVar itself, unless you want to specifially call a copy of MyVar that is global rather than a local copy (which may have a different value).
Lua Code:
  1. myVar = "apple"
  2. local myVar = "banana"
  3. print(myVar) --> "banana"
  4. print(_G.myVar) --> "apple"
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
01-22-14, 03:37 PM   #19
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
To your second post, Fizzlemizz, those are functions and not tables. That would not work the same way, as when you save a table to a different variable name (or, local vs global variable) a pointer is created to the same table that is in memory.
Lua Code:
  1. local myTable = {}
  2. _G.myTable = myTable
  3. print(myTable) --> table:009238 (reference/index to table in memory)
  4. print(_G.myTable) --> table:009238 (same table! just using a different variable for access)
Making a change to the table will be accessible from either way you access it. (Think front and back doors on your house. You can paint the kitchen yellow, and it will still be yellow no matter which door you come in from.) If you want to actually copy the table and have two different tables with the same contents, you have to do that manually.

Functions don't work the same way.
Lua Code:
  1. local function myFunc() end
  2. _G.myFunc = myFunc
  3. print(myFunc) --> function:093hj1k
  4. print(_G.myFunc) --> function:1lk098a
Functions get "copied", so you now have two separate functions independent of one another. It's just like doing
Lua Code:
  1. varA = "apple"
  2. varB = varA
  3. varA = "banana"
  4. print(varA) --> "banana" (because we changed it on line 3)
  5. print(varB) --> "apple" (because varA still was "apple" when assigning varB on line 2)
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
01-22-14, 05:29 PM   #20
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,877
Thank you Seerah et. al.

For the final piece of the puzzle, is Clamsoda's assertion (belief) correct that

"_G is just a table in the global scope, "

and that is where you store (copy, place) variables and functions you want make accessible to other addons (directories under \Interface\Addons).

I've got some ancient addons that I'm certain are rank offenders in cluttering up the global scope and I would very much like to make them better community players.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » funcName = function(p1, p2, ...) instead of function funcName(p1, p2, ...)?


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