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!
An explanation of Classes in Lua for people coming from an Object-Oriented background
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 14
- Joined: Fri Jan 22, 2016 3:25 am
- zorg
- Party member
- Posts: 3468
- 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
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.
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.
Last edited by zorg on Fri Jun 10, 2016 7:04 am, edited 1 time in total.
Me and my stuff True 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.
-
- Prole
- Posts: 14
- Joined: Fri Jan 22, 2016 3:25 am
Re: An explanation of Classes in Lua for people coming from an Object-Oriented background
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
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.
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:The method I’m describing is the only way to achieve class-like functionality.
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()
-
- Prole
- Posts: 14
- Joined: Fri Jan 22, 2016 3:25 am
Re: An explanation of Classes in Lua for people coming from an Object-Oriented background
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
Yep, good point by airstruck.
I've seen this approach written as:
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).
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
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
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.
Who is online
Users browsing this forum: Semrush [Bot] and 5 guests