attempt to index local 'self' (a function value) error
2 replies, posted
This is my first attempt at making a custom VGUI button.
So far, this is my code in the file "addon/lua/vgui/cButton.lua":
[code]
cButton = {}
cButton.OnMouseDown = nil
cButton.OnMouseUp = nil
cButton.State = nil
cButton.ClickFunc = nil
function cButton:Init()
self.State = 0
self.Text = "text"
end
function cButton:Paint()
if ( self.State == 1 ) then
surface.SetDrawColor(176,120,34,230)
surface.DrawRect( 0,0,self:GetWide(),self:GetTall() )
else
surface.SetDrawColor(166,110,24,230)
surface.DrawRect( 0,0,self:GetWide(),self:GetTall() )
end
draw.DrawText( self.Text, self.Font, self:GetWide() / 2, self:GetTall() / 2 - 14 / 2, Color( 255,255,255,255 ), 1 )
return false
end
function cButton:OnMousePressed( m )
self.State = 1
self.ClickFunc()
end
function cButton:OnMouseReleased( m )
self.State = 0
end
function cButton:SetText(text)
self.Text = text
end
function cButton:SetClick(func)
self.ClickFunc = func //<---- this is the error line.
end
vgui.Register("cButton", cButton, "Panel")
[/code]
and the code for creating it is:
[code]
local cButtonTest = vgui.Create("cButton", frame)
cButtonTest:SetSize(frame:GetWide() - 24, 24)
cButtonTest:SetPos(12, 24)
cButtonTest:SetText("SEARCH PLAYER")
cButtonTest.SetClick(function()
print("test")
end)
[/code]
And the error comes up as soon as the .SetClick function is called:
[code]
[ERROR] addons/arma_cops_menu/lua/vgui/cbutton.lua:38: attempt to index local 'self' (a function value)
1. SetClick - addons/arma_cops_menu/lua/vgui/cbutton.lua:38
2. unknown - addons/arma_cops_menu/lua/autorun/files/client.lua:89
3. unknown - lua/includes/modules/concommand.lua:69
[/code]
What is the cause of this and how can I fix? I just never saw this error before -_-
Should working.
[lua]
cButton = {}
AccessorFunc( PANEL, "m_sText", "Text" )
AccessorFunc( PANEL, "m_sFont", "Font" )
/*---------------------------------------------------------
---------------------------------------------------------*/
function cButton:Init()
self:SetText( "text")
self:SetFont("DermaDefault")
end
/*---------------------------------------------------------
---------------------------------------------------------*/
function cButton:ClickFunc()
end
/*---------------------------------------------------------
---------------------------------------------------------*/
function cButton:OnMousePressed( m )
// predict spam the function
end
/*---------------------------------------------------------
---------------------------------------------------------*/
function cButton:OnMouseReleased( m )
if( m == MOUSE_LEFT ) then
self:ClickFunc()
else
end
end
/*---------------------------------------------------------
---------------------------------------------------------*/
function cButton:Paint( w, h )
if ( self:IsHovered() ) then
surface.SetDrawColor(176,120,34,230)
surface.DrawRect( 0, 0, w, h )
else
surface.SetDrawColor(166,110,24,230)
surface.DrawRect( 0, 0, w, h)
end
draw.DrawText( self.m_sText, self.m_sFont, w / 2, h / 2 - 14 / 2, Color( 255,255,255,255 ), 1 )
end
derma.DefineControl( "cButton", "A standard Button", cButton, "DPanel" )
local cButtonTest = vgui.Create("cButton", frame)
cButtonTest:SetSize(frame:GetWide() - 24, 24)
cButtonTest:SetPos(12, 24)
cButtonTest:SetText("SEARCH PLAYER")
function cButtonTest:ClickFunc()
// code
Msg("pressed")
end
[/lua]
[lua]
local cButtonTest = vgui.Create("cButton", frame)
cButtonTest:SetSize(frame:GetWide() - 24, 24)
cButtonTest:SetPos(12, 24)
cButtonTest:SetText("SEARCH PLAYER")
cButtonTest.SetClick(function() -- this is the problem
print("test")
end)
[/lua]
Solution:
[lua]
cButtonTest:SetClick(function() print("test") end)
[/lua]
Another solution:
[lua]
cButtonTest.SetClick(cButtonTest, function() print("test") end)
[/lua]
Why?
When you call a table member function with a semicolon (:), the table you're calling it on becomes the first argument -> 'self'.
But because you called it with a dot (.), the first argument was the function you gave it /the one with print("test")/ and it tried to assign to [supplied function argument].ClickFunc - that obviously raised an error.
[lua]
local hello = {}
hello.test = function(self, a, b, c)
print(self, a, b, c)
end
function hello:another(a, b, c)
-- this does the same, but because the function is defined with a semicolon,
-- the 'self' variable is generated automagically - the function signature/arguments list is changed
-- so it's pretty much equal to hello.test
print(self, a, b, c)
end
hello.test(1, 2, 3)
hello:test(1, 2, 3)
print("aaaaa")
hello.another(1, 2, 3)
hello:another(1, 2, 3)
-- Output:
-- 1 2 3 nil
-- table: 0x6c0680 1 2 3
-- aaaaa
-- 1 2 3 nil
-- table: 0x6c0680 1 2 3
[/lua]
Sorry, you need to Log In to post a reply to this thread.