Thread Tools Display Modes
08-17-14, 10:11 PM   #1
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,877
Parameter passing difference, Colon vs Period.

I'm sure I'm missing something obvious but using the code below, pressing the f1 button returns
LeftButton, nil
Pressing the f2 button returns:
table: 0000000043259BB0, LeftButton
Why the difference?

Code:
local _, Settings = ...

function Settings:TestClick(p1, p2)
	print(tostring(p1) .. ", " .. tostring(p2))
end
function Settings:CreateOptions()
	local f = CreateFrame("Frame")
	f:SetSize(10, 80)
	f:ClearAllPoints()
	f:SetPoint("CENTER", UIParent)
	f.test = CreateFrame("Button", "Test_Button", f, "UIPanelButtonTemplate")
	f.test:SetScript("OnClick", function(self, button)
		if self.clickextra then
			self.clickextra(self, button)
		end
	end)
	f.test.clickextra = Settings.TestClick
	f.test:ClearAllPoints()
	f.test:SetPoint("CENTER")
	return f
end

local function Test2Click(p1, p2)
	print(tostring(p1) .. ", " .. tostring(p2))
end
local function CreateOpts()
	local f = CreateFrame("Frame")
	f:SetSize(10, 80)
	f:ClearAllPoints()
	f:SetPoint("CENTER", UIParent, 0, -40)
	f.test = CreateFrame("Button", "Test_Button", f, "UIPanelButtonTemplate")
	f.test:SetScript("OnClick", function(self, button)
		if self.clickextra then
			self.clickextra(self, button)
		end
	end)
	f.test.clickextra = Test2Click
	f.test:ClearAllPoints()
	f.test:SetPoint("CENTER")
	return f
end

local f1 = Settings:CreateOptions()
local f2 = CreateOpts()
Edit: and changing
self.clickextra(self, button)
to self.clickextra(1, self, button)
in Settings:CreateOptions() produces the same result as pressing f2.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 08-18-14 at 11:30 AM. Reason: To make the title more appropriate for future reference
  Reply With Quote
08-17-14, 11:33 PM   #2
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,322
You might try this:
Code:
local function Test2Click(self, p1, p2)
This is because the first function is defined as a method, takes the first arg and assigns it to the local self. The second and third args go to p1 and p2 respectively. This normal function definition doesn't shift the args like that and causes the anomaly you witnessed. To compensate for this, you need to explicitly define self as the first arg.
__________________
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
08-17-14, 11:35 PM   #3
Gethe
RealUI Developer
 
Gethe's Avatar
Premium Member
Featured
Join Date: Sep 2008
Posts: 942
Originally Posted by Fizzlemizz View Post
I'm sure I'm missing something obvious but using the code below, pressing the f1 button returns


Pressing the f2 button returns:


Why the difference?

<snip>

Edit: and changing

in Settings:CreateOptions() produces the same result as pressing f2.
The colon notation used in Settings:TestClick absorbs the first arg given as self. If you add
self:GetName(),
as the first arg to the Settings:TestClick print call, it will return:
Test_Button LeftButton, nil
With your edit, the above will return with this error:
Code:
1x MyFirstAddOn\code.lua:7: attempt to index local 'self' (a number value)
MyFirstAddOn\code.lua:7: in function `clickextra'
MyFirstAddOn\code.lua:17: in function <MyFirstAddOn\code.lua:15>

Locals:
self = Test_Button {
 0 = <userdata>
 clickextra = <function> defined @MyFirstAddOn\code.lua:6
 Right = <unnamed> {
 }
 Middle = <unnamed> {
 }
 Left = <unnamed> {
 }
}
button = "LeftButton"

In Test2Click, p1 is technically 'self'. Even though it's not named that, the reference still gets passed to the first arg.

ps: print() will automaticly tostring() each arg.
__________________
Knowledge = Power; Be OP


Last edited by Gethe : 08-17-14 at 11:50 PM. Reason: clarify
  Reply With Quote
08-18-14, 12:16 AM   #4
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,877
I've learned something new today, thank you both.

Lua is an intersting beast full of surprises, both good and bad this one, not so much on the good side .

Edit: on second thought, a lightbulb moment so the surprise swings very much back to the good side.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 08-18-14 at 12:26 AM.
  Reply With Quote
08-18-14, 12:23 AM   #5
Oppugno
A Fallenroot Satyr
Join Date: Sep 2012
Posts: 22
Although it has already been said this is the formal reason why it is happening:
Originally Posted by Lua 5.1 Reference Manual
The colon syntax is used for defining methods, that is, functions that have an implicit extra parameter self. Thus, the statement
function t.a.b.c:f (params) body end
is syntactic sugar for
t.a.b.c.f = function (self, params) body end
As you would think this also applies when calling functions.

These two functions are identical
Lua Code:
  1. function Table.Print(self)
  2.     print(self)
  3. end
  4.  
  5. function Table:Print()
  6.     print(self)
  7. end
The second one uses the colon notation and thus 'self' is implicitly the table in which it is defined.

These two function calls are also identical, in their resulting outputs.
Lua Code:
  1. Table:Print()
  2. Table.Print(Table)
When using the dot notation you explicitly define what the 'self' variable will be by calling the function with that passed as the first argument.

Note that the 'self' variable does not need be the table in which the function is defined in.
Lua Code:
  1. Table.Print("Orange")
Will work equally well. However, this time outputting "Orange" instead of the table reference.

P.S. It seems Fizzlemizz got what they needed while I was typing this up. Leaving it here for anyone that stumbles upon it.
  Reply With Quote
08-19-14, 09:15 PM   #6
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Originally Posted by Gethe View Post
ps: print() will automaticly tostring() each arg.
It will also print any number of arguments passed to it. No need to create a string and concatenate it all together.

print(p1, p2)
__________________
"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

WoWInterface » Developer Discussions » Lua/XML Help » Why are these different?

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