An explanation of Classes in Lua for people coming from an Object-Oriented background

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
m0nkeybl1tz
Prole
Posts: 10
Joined: Fri Jan 22, 2016 3:25 am

An explanation of Classes in Lua for people coming from an Object-Oriented background

Post by m0nkeybl1tz »

Hey guys, so I've recently been looking into how to implement class-like functionality in Lua, seeing as that's what I'm used to (coming from a Unity/C# background). I got the implementation working, but I really struggled with understanding the logic behind them. I think I finally have a grasp of how it all works, and I put together a blog post explaining it.

I hope this is helpful for some of you, and please if you have any comments or questions don't hesitate to share!
User avatar
zorg
Party member
Posts: 3158
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: An explanation of Classes in Lua for people coming from an Object-Oriented background

Post by zorg »

Quite nice, though i suspect you wanted to write "self.whatever" in each function with a colon (:) syntax, since the current way won't work with more than one created instance, if at all.

There are a few pointers that were made before on the forum though, that you could check out :3

http://love2d.org/forums/viewtopic.php? ... 99#p195899 (function definition/calls, diff. between '.' and ':')
http://love2d.org/forums/viewtopic.php? ... 37#p196337 ("class" example)
http://love2d.org/forums/viewtopic.php? ... 10#p196010 (lua ambiguous parsing of three parens across newlines)

Also feel free to ask if something's not clicking, i hear this forum's nice to everyone.
Last edited by zorg on Fri Jun 10, 2016 7:04 am, edited 1 time in total.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
m0nkeybl1tz
Prole
Posts: 10
Joined: Fri Jan 22, 2016 3:25 am

Re: An explanation of Classes in Lua for people coming from an Object-Oriented background

Post by m0nkeybl1tz »

Good call on the self stuff, I just went back and changed it. And yeah, I know there's been a good amount of help/advice on the topic, but I had a hard time finding one document that covered everything in one place.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: An explanation of Classes in Lua for people coming from an Object-Oriented background

Post by airstruck »

Not a bad read, I liked it. I disagree with these two points, though.
Metatables [are] the final key to having full class functionality in Lua.
The method I’m describing is the only way to achieve class-like functionality.
True, metatables and prototype-style inheritance are the usual way to do classical OOP in Lua, but not the only way. You can have classes without metatables if you assign methods in the function that instantiates the class:

Code: Select all

-- character.lua

local function moveLeft (self)
    self.x = self.x - 1
end

local function moveRight (self)
    self.x = self.x + 1
end

return function (x, y)
    local instance = {}
    
    instance.x = x
    instance.y = y
    instance.moveLeft = moveLeft
    instance.moveRight = moveRight
    
    return instance
end

Code: Select all

-- enemy.lua

local Character = require 'character'

local function attack (self)
    print(self.name .. ' attacks you!')
end

return function (x, y)
    local instance = Character(x, y) -- extends Character
    
    instance.name = 'an enemy'
    instance.attack = attack
    
    return instance
end

Code: Select all

-- main.lua

local Enemy = require 'enemy'

local badGuy = Enemy(10, 10)
badGuy:moveLeft()
badGuy:attack()
m0nkeybl1tz
Prole
Posts: 10
Joined: Fri Jan 22, 2016 3:25 am

Re: An explanation of Classes in Lua for people coming from an Object-Oriented background

Post by m0nkeybl1tz »

Huh, that's super interesting, thanks for sharing! It's crazy how flexible Lua is...
User avatar
ivan
Party member
Posts: 1737
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: An explanation of Classes in Lua for people coming from an Object-Oriented background

Post by ivan »

Yep, good point by airstruck.
I've seen this approach written as:

Code: Select all

-- character.lua
return function (x, y)
  local instance = {}
  function instance.moveLeft()
    x = x - 1
  end
  function instance.moveRight()
    x = x + 1
  end
  return instance
end
Where the locals x,y are accessible by all functions in "instance".
Another consequence is that you don't need to use ":" and "self" at all.
It works well for certain things, but the performance is worse than metatables (especially for short-lived objects).
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: An explanation of Classes in Lua for people coming from an Object-Oriented background

Post by airstruck »

ivan wrote:I've seen this approach written as:

Code: Select all

[/quote]

Yeah, I've seen this too; I think closures can be very useful for some things, but wouldn't recommend using them like this. The "self-ness" of objects is a major point of OOP, and that "self-ness" means you already have a place to store relevant state, it doesn't need to be stored in a closure.

Private members are the only real advantage, but they're not worth much in my opinion. Your code won't be as extensible as it would in most languages with "true" private members, because those languages will generally also have protected members, and you can easily change your private members to protected when you need to access them from a derived type.

[quote]It works well for certain things, but the performance is worse than metatables (especially for short-lived objects).[/quote]

I'd expect that to be true for the closure-based solution, but not necessarily for the closure-less solution. I'd expect the closure-less solution to be slightly heavier than metatables on object creation and slightly lighter on method resolution (although I think the difference would be very minor and wouldn't affect overall performance in a meaningful way). It would be interesting to compare the performance of all 3 solutions, though.
Post Reply

Who is online

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