Passing a 'self' function as a parameter

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Starnub
Prole
Posts: 6
Joined: Thu Nov 07, 2019 6:10 am

Passing a 'self' function as a parameter

Post 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!
User avatar
Imagic
Prole
Posts: 45
Joined: Mon Sep 30, 2019 8:20 am
Contact:

Re: Passing a 'self' function as a parameter

Post 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.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Passing a 'self' function as a parameter

Post 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

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Passing a 'self' function as a parameter

Post 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.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Passing a 'self' function as a parameter

Post by raidho36 »

This and many other interesting features are detailed in the Programming in Lua book and Lua user manual.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 3 guests