Page 1 of 1

Passing a 'self' function as a parameter

Posted: Thu Nov 07, 2019 6:28 am
by Starnub
I'm not really sure how to word this properly, but what I want to do is pass a function that requires the self argument to another outside function. Say I have a Button object:

Code: Select all

local button = {}
button.__index = button

function newButton(f)
	return setmetatable({function = f}, button)
end

function button:update(dt)
	-- Assume clicked() is a pre-written function.
	if clicked(self) then self.function() end
end
And then I want to tie a button to a custom Square object:

Code: Select all

local square = {}
square.__index = square

function newSquare(f)
	return setmetatable({n = 0, button = newButton(?)}, square)
end

function square:increment()
	self.n = self.n + 1
end
How would I pass the "square:increment()" function into the "newButton()" function as a parameter? Sorry if this is confusing, I'm still trying to wrap my head around coding. Any help would be greatly appreciated!

Re: Passing a 'self' function as a parameter

Posted: Thu Nov 07, 2019 4:20 pm
by Imagic

Code: Select all

square:increment(...)
is syntactic sugar for

Code: Select all

square.increment(square, ...)

methods are functions and self is not a property of a function, it's a parameter (https://www.lua.org/manual/5.1/manual.html#2.5.8).

Based on that, you may be able to redesign your code.

Re: Passing a 'self' function as a parameter

Posted: Thu Nov 07, 2019 5:05 pm
by s-ol

Code: Select all

function newSquare(f)
        local square = setmetatable({ n = 1 }, square)
        square.button = newButton(function () square:increment end)
        return square
end

Re: Passing a 'self' function as a parameter

Posted: Thu Nov 07, 2019 6:20 pm
by pgimeno
This:

Code: Select all

function square:increment()
is syntactic sugar for this:

Code: Select all

function square.increment(self)
which is in turn syntactic sugar for this:

Code: Select all

square.increment = function (self)
therefore the function you're looking for is stored in square.increment.

However, you need some method to pass the object, and a closure like the one s-ol has posted is an easy way. What Imagic has posted is right, but it applies to function calls, not to function definitions. What s-ol has posted almost works (it needs parentheses after square:increment, otherwise that causes a syntax error), but it sets n = 1 for no good reason.

Re: Passing a 'self' function as a parameter

Posted: Fri Nov 08, 2019 5:37 am
by raidho36
This and many other interesting features are detailed in the Programming in Lua book and Lua user manual.