Thread Tools Display Modes
04-12-11, 06:22 PM   #1
Waky
A Cobalt Mageweaver
 
Waky's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2010
Posts: 200
Is there a difference?

I've seen people do these two things in their code, and I was wondering if it made a difference:

#1
Code:
local funcName = function(x,y,z)
 --[[ Fancy code goes here ]]
end
#2
Code:
local function funcName(x,y,z)
 --[[ Fancy code goes here ]]
end
Lemme know! Thanks!
  Reply With Quote
04-12-11, 06:26 PM   #2
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by Waky View Post
I've seen people do these two things in their code, and I was wondering if it made a difference:

#1
Code:
local funcName = function(x,y,z)
 --[[ Fancy code goes here ]]
end
#2
Code:
local function funcName(x,y,z)
 --[[ Fancy code goes here ]]
end
Lemme know! Thanks!
Nope. Second is just a different way of writing the first. The first does have it's uses, though.

http://lua-users.org/wiki/FunctionsTutorial

Last edited by Nibelheim : 04-12-11 at 06:31 PM.
  Reply With Quote
04-12-11, 07:33 PM   #3
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Yes, they are the same thing, and are just a different way of writing
I want to recommend an complementary, although shorter, link:

http://old.wowace.com/wiki/Coding_Ti...tactical_sugar
  Reply With Quote
04-12-11, 07:51 PM   #4
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
On the subject (kind of), is it possible to add a new function, let's say:

string:fc = function() return self:sub(1, 1):upper() end
local str = "hello world"
print(str:fc()) -- prints "H"

Not sure if it's doable without causing taint and break other addons, considering string is quite global.
  Reply With Quote
04-12-11, 08:08 PM   #5
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by Vladinator View Post
On the subject (kind of), is it possible to add a new function, let's say:

string:fc = function() return self:sub(1, 1):upper() end
local str = "hello world"
print(str:fc()) -- prints "H"

Not sure if it's doable without causing taint and break other addons, considering string is quite global.
No reason why not. Hell, you can even modify existing functions, at the risk of blowing everything up that relies on the function working a certain way :P

Code:
string.format = function(...) print("Haha!") end
Basically, "string", like all things, is simply an object, with multiple functions attached to it. Feel free to add your own.

Code:
string.insertsmiley = function(s) return s.." :)" end
  Reply With Quote
04-13-11, 01:44 AM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
From personal experience, in functionality, both methods are equal. There is a difference in how Lua handles each method when referencing externals (variables or objects stored outside the function, either by upvalue or global).

For some strange reason, when defining a function using "function name()" syntax, the compiler takes a C-style behavior in which any externals must be defined prior to declaration. The "name=function()" syntax is loose in this respect as long as the externals are defined before the function is called.

If I had to take a guess, this would mean the "function name()" syntax compiles the function as the main chunk is loaded and the "name=function()" syntax stores a representation of the function to be compiled when called for the first time.
__________________
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)

Last edited by SDPhantom : 04-13-11 at 01:48 AM.
  Reply With Quote
04-13-11, 02:30 AM   #7
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by Vladinator View Post
On the subject (kind of), is it possible to add a new function, let's say:

string:fc = function() return self:sub(1, 1):upper() end
local str = "hello world"
print(str:fc()) -- prints "H"

Not sure if it's doable without causing taint and break other addons, considering string is quite global.
The only way to directly define a colon-notation version of the function is:

Code:
function string:fc()
        return self:sub(1, 1):upper()
end
This is perfectly legal and non-tainting, since the Lua string library in no way controls or impacts the WoW API.

To do it the way you alluded to, you'd need to do it thusly:

Code:
string.fc = function(self)
        return self:sub(1, 1):upper()
end
At that point, you'd be able to call the function using colon-notation.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.

Last edited by Torhal : 04-13-11 at 02:34 AM.
  Reply With Quote
04-13-11, 05:39 AM   #8
Foxlit
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 91
Originally Posted by SDPhantom View Post
From personal experience, in functionality, both methods are equal. There is a difference in how Lua handles each method when referencing externals (variables or objects stored outside the function, either by upvalue or global).

[...]
The difference you describe does not exist. Try illustrating it with a code example.
__________________
... and you do get used to it, after a while.
  Reply With Quote
04-13-11, 06:28 AM   #9
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
One last question then, hehe.

Would it be possible to have a table where you can make ) functions? Let's say you got the table tbl and I'd like to make a tbl:add(object), would it be possible to define that function? I am thinking of tbl like the string example, it would work on any table basically. In essence it won't work just for tbl but for any kind of {} -I guess this is where metatable comes in or? I'm not too good with metatables but learning.
  Reply With Quote
04-13-11, 08:43 AM   #10
Xinhuan
A Chromatic Dragonspawn
 
Xinhuan's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 174
Originally Posted by Foxlit View Post
The difference you describe does not exist. Try illustrating it with a code example.
Foxlit is correct, there is no difference in the way upvalues and globals are handled in both cases.

To answer the original poster, there are still differences between the 2 methods, but it only affects recursive functions. Look at these 2 examples:

#1
Code:
local f = function()
    f()
end
f()
#2
Code:
local function f()
    f()
end
f()
When you run f() on #1, you will get the error "attempt to call global 'f' (a nil value)" because the f referred to within the function doesn't exist yet. The function is compiled first, then assigned to local f - that is, the local f doesn't exist until after the assignment. So during the function's compilation, the f referred to inside the function is assumed to be on _G["f"] since there isn't any existing upvalue f.

When you run f() on #2, you will get the "stack overflow" with a stack trace of f() calling itself, because the syntactic sugar of #2 is actually just a shortcut to do this:

#2
Code:
local f
f = function()
    f()
end
f()
Here, the upvalue referenced in the function compiles correctly.
__________________
Author of Postal, Omen3, GemHelper, BankItems, WoWEquip, GatherMate, GatherMate2, Routes and Cartographer_Routes

Last edited by Xinhuan : 04-13-11 at 08:46 AM.
  Reply With Quote
04-13-11, 08:53 AM   #11
Xinhuan
A Chromatic Dragonspawn
 
Xinhuan's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 174
Originally Posted by Vladinator View Post
One last question then, hehe.

Would it be possible to have a table where you can make ) functions? Let's say you got the table tbl and I'd like to make a tbl:add(object), would it be possible to define that function? I am thinking of tbl like the string example, it would work on any table basically. In essence it won't work just for tbl but for any kind of {} -I guess this is where metatable comes in or? I'm not too good with metatables but learning.
Yes, via the use of metatables.

Code:
local myFunctions = {}
myFunctions.add = function(t, obj)
   --Add obj to table t
   table.insert(t, obj)
end

local someTable = {}
setmetatable(someTable, {__index = myFunctions})

-- From this point onwards, whenever you refer to a someTable[key] and
-- key doesn't exist in someTable, it will lookup myFunctions[key] and return that instead.

someTable:add(1)
-- The above is the same as someTable.add(someTable, 1)
-- You might want to read about the : versus . calling notation.
-- Since someTable.add doesn't exist, Lua looks for myFunctions.add
-- and finally calls myFunctions.add(someTable, 1)

someTable:blah(2)
-- The above does the same thing, but since someTable.blah and myFunctions.blah
-- are both nil, you end up getting an error about calling a function on a nil object.
Note that you have to attach the {__index = myFunctions} metatable to each table you want this "magic" to work on. Multiple tables can share the same metatable (recommended).
__________________
Author of Postal, Omen3, GemHelper, BankItems, WoWEquip, GatherMate, GatherMate2, Routes and Cartographer_Routes

Last edited by Xinhuan : 04-13-11 at 08:57 AM.
  Reply With Quote
04-14-11, 06:15 AM   #12
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Thanks a bunch for clarifying things!
  Reply With Quote
04-15-11, 12:57 AM   #13
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
I was just posting what happened when I try using the "function name()" syntax when I was working on my own addons.

Code:
local function func1()
	print(type(var));
end

local func2=function()
	print(type(var));
end

local var="some string";

func1();
func2();
I could still be wrong, but when I had code like this, func1() would print "nil" while func2() would print "string".
This is assuming you don't have a global named var defined.





Code:
local var="some string";

local function func1()
	print(type(var));
end

local func2=function()
	print(type(var));
end

func1();
func2();
This would end up with both functions printing "string".
Notice the line defining the local var has been moved above the function definitions in this example.
__________________
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)

Last edited by SDPhantom : 04-15-11 at 01:02 AM.
  Reply With Quote
04-15-11, 03:25 PM   #14
Foxlit
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 91
Originally Posted by SDPhantom View Post
Code:
local function func1()
	print(type(var));
end

local func2=function()
	print(type(var));
end

local var="some string";

func1();
func2();
I could still be wrong, but when I had code like this, func1() would print "nil" while func2() would print "string".
This is assuming you don't have a global named var defined.
Both do print nil in this case.
__________________
... and you do get used to it, after a while.
  Reply With Quote
04-16-11, 01:59 PM   #15
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
Up until here, it was theory based on a symptom of errors I kept getting when switching from one syntax to another. After actual testing, this doesn't seem to be the case. I don't know how else to explain the errors, but they were there and it was related to the topic I brought up.

This was a long time ago and has long since been fixed by moving the related local constants above the function declarations.
__________________
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

WoWInterface » Developer Discussions » Lua/XML Help » Is there a difference?


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