Page 1 of 1
An explanation of Classes in Lua for people coming from an Object-Oriented background
Posted: Tue Jun 07, 2016 8:36 pm
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!
Re: An explanation of Classes in Lua for people coming from an Object-Oriented background
Posted: Tue Jun 07, 2016 9:25 pm
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
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.
Re: An explanation of Classes in Lua for people coming from an Object-Oriented background
Posted: Wed Jun 08, 2016 1:35 am
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.
Re: An explanation of Classes in Lua for people coming from an Object-Oriented background
Posted: Wed Jun 08, 2016 6:41 am
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()
Re: An explanation of Classes in Lua for people coming from an Object-Oriented background
Posted: Thu Jun 09, 2016 1:25 am
by m0nkeybl1tz
Huh, that's super interesting, thanks for sharing! It's crazy how flexible Lua is...
Re: An explanation of Classes in Lua for people coming from an Object-Oriented background
Posted: Thu Jun 09, 2016 5:43 am
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).
Re: An explanation of Classes in Lua for people coming from an Object-Oriented background
Posted: Thu Jun 09, 2016 8:51 pm
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.