• 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.