Page 1 of 1

Referencing "self" inside of class functions outside of class creation

Posted: Mon Oct 30, 2017 10:35 am
by baconhawka7x
So I have a "Player.lua" file that returns a function, that creates / returns a class:

player.lua

Code: Select all

function CreatePlayer()
  local player={
    load=load,
    update=update,
    draw=draw,
  }
  setmetatable({},player)
  player.__index=player
  return player
end
As you see the class has 3 variables, load update and draw. Each of those are defined in the same file as local functions, I thought defining them inside of the player table would get messy. However, inside of those, the only way to manipulate the player's values is to pass the player class table created by that function as an argument, for example -

Code: Select all

var newPlayer=CreatePlayer()
newPlayer.load(newPlayer)
I'm very new to Lua's "classes" and I was wondering if there is a way around this? I've seen people use "self.value" but I'm not sure exactly how that works. I'm betting I have my "Player.lua" set up all wrong. Any help would be very appreciated, I've been looking for an answer for this for a while, but it's kind of difficult to figure out what to look up!

Re: Referencing "self" inside of class functions outside of class creation

Posted: Mon Oct 30, 2017 10:49 am
by bartbes
Well, the call site change is simple:

Code: Select all

newPlayer.load(newPlayer)
-- is equivalent to
newPlayer:load()
As for the definition site, you can just name the first parameter self. A similar shorthand exists there:

Code: Select all

function sometable:somefunc(arg)
end
-- is equivalent to
function sometable.somefunc(self, arg)
end

Re: Referencing "self" inside of class functions outside of class creation

Posted: Mon Oct 30, 2017 10:52 am
by baconhawka7x
Oh perfect! Thank you for the quick answer!

This works well, I'm now defining those 3 functions inside of the CreateClass function with that shorthand.

Code: Select all

function CreatePlayer()
  local newPlayer={}
  setmetatable({},newPlayer)
  newPlayer.__index=newPlayer

  function newPlayer:load()
  end
  function newPlayer:update(dt)
  end
  function newPlayer:draw()
  end

  return newPlayer
end

Re: Referencing "self" inside of class functions outside of class creation

Posted: Mon Oct 30, 2017 11:00 am
by bartbes
I should probably note that the setmetatable call is useless, since it sets the metatable of a temporary table you immediately discard.

The usual way people do this is by creating these functions once, instead of for every object, and then making objects have a metatable with an __index metafield that points to the function, as follows:

Code: Select all

local player = {}
player.__index = player

function player:load()
end
function player:update(dt)
end
function player:draw()
end

function CreatePlayer()
  local newPlayer={}
  setmetatable(newPlayer, player)
  return newPlayer
end

-- or in one go:
function CreatePlayer()
  return setmetatable({}, player)
end