Page 2 of 3
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Sun Jan 29, 2017 4:54 pm
by lukems
I'm using a lot of your libraries lately, great stuff, thanks for sharing them with us!
While using Middleclass I was wondering if you guys have a nice way to declare properties with it.
Do note that I'm still learning my way through Lua and Löve, coming from Python
This is how I'm currently doing it:
Code: Select all
local class = require('middleclass')
Rect = class('Rect')
local __setters = {}
local __getters = {}
__getters.__index = __getters
__setters.__index = __setters
function __getters:right()
return self.x + self.w
end
function __setters:right(v)
self.x = self.x + v - self.right
end
function Rect:initialize(x, y, w, h)
self.x = x
self.y = y
self.w = w
self.h = h
end
function Rect:__index(k)
return __getters[k](self)
end
function Rect:__newindex(k, v)
local fn = __setters[k]
if fn ~= nil then
fn(self, v)
else
rawset(self, k, v)
end
end
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Sun Jan 29, 2017 10:41 pm
by kikito
Hi there! Thanks for your kind words.
Let me start by saying that I am not a huge fan of getters/setters in Lua. In other languages, I can accept them; for example in ruby, they are integrated in the language's message-passing mechanism.
But in Lua they are extra syntactic sugar, and risk making things more "magical" (unexpected to someone unfamiliar with the code).
That said, your approach is a good approximation at implementing properties. I would suggest some changes though.
- I would put the properties-related code in a mixin, so that it can be easily reused by multiple classes without having to do "the metatable dance" on every class.
- I would still require getter and setter methods. That way, if someone (like me) doesn't want to use properties, they have the option to use the "old fashioned" methods
- Given the previous point, I would build the properties by convention: if there is a set_xxx method, then xxx is setable via obj.xxx = too. Similarly, if there is a get_xxx method, then xxx is gettable via obj.xxx. This way you would not even need the 'setters' or 'getters' variables.
That would give us this mixin:
Code: Select all
-- properties.lua
local Properties = {}
function Properties:__index(k)
return self['get_' .. k]
end
function Properties:__newIndex(k, v)
local fn = self['set_' .. k]
if fn then
fn(self, v)
else
rawset(self, k, v)
end
end
end
return Properties
Usage:
Code: Select all
local class = require('middleclass')
local Properties = require('properties')
local Rect = class('Rect'):include(Properties)
function Rect:initialize(x, y, w, h)
self.x = x
self.y = y
self.w = w
self.h = h
end
function Rect:get_right()
return self.x + self.w
end
function Rect:set_right(right)
self.x = self.x + right - self.right
end
r = Rect:new(10,10, 100, 100)
print(r.right) -- 110
print(r:get_right()) -- 110
r.right = 200
print(r.right) -- 200
print(r.x) -- 100
r.name = 'peter'
print(r.name) -- peter
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Mon Jan 30, 2017 3:08 am
by lukems
Thanks for your quick answer, that looks great!
Maybe I'll be able to drop those properties in the future, when I get over my Python bias...
I'm happy to say that your nice and clean implementation is also faster, taking only 66% of the time mine did on some tests.
Great news, considering I'm going to use those Rect's a lot!
I've done two changes on
properties.lua to get it working here.
- return self['get_' .. k] was raising a stack overflow error so I'm now using self.class.__instanceDict["get_" .. k] instead;
- When a nil value was (not) found, an error was raised (by trying to call it as a function), so I've included a check.
(And a minor tweak, comparing things specifically against
nil gave it a big performance boost here

).
Code: Select all
-- properties.lua
local Properties = {}
function Properties:__index(k)
local getter = self.class.__instanceDict["get_" .. k]
if getter ~= nil then
return getter(self)
end
end
function Properties:__newindex(k, v)
local setter = self["set_" .. k]
if setter ~= nil then
setter(self, v)
else
rawset(self, k, v)
end
end
return Properties
Maybe you could include this mixin as a recipe/example at middleclass library wiki. For people like me

Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Mon Jan 30, 2017 11:29 am
by kikito
Great news, considering I'm going to use those Rect's a lot!
If you are planning to use it a lot, for intensive calculus etc, I would recommend you to measure how fast it is to not use middleclass at all too. Middleclass (and, in fact, any object-oriented library) is not a good fit for super-tight intensive calculations. For example, I would not use it for vectors or matrixes. For those, I think plain numbers + functions work best. There is no metatables - and there is no tables either. So your intensive code generates as little garbage as possible. That's
what I did for the rectangles in bump.. Vrld has done something for vectors in
vector-light.
I've done two changes on properties.lua to get it working here.
Ok!
(And a minor tweak, comparing things specifically against nil gave it a big performance boost here
That is ... unintuitive. As far as I know,
if x is logically equivalent to
if x ~= nil when x can't be
false. And it seems that the first one should be faster since it is doing less. But that's efficiency for you; one never knows until the test is run.
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Mon Jan 30, 2017 3:15 pm
by DanielPower
Thank you again Kikito for your fantastic libraries. I use middleclass in all of my projects, and almost always end up using bump and inspect. I also wanted to mention that your blog taught be a lot about writing and using modules, and oop. I'll be upgrading to middleclass 4 when I get the time to start working on my game again. I'll report back with results compared to middleclass 3.
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Mon Jan 30, 2017 4:06 pm
by kikito
DanielPower wrote:Thank you again Kikito for your fantastic libraries. I use middleclass in all of my projects, and almost always end up using bump and inspect. I also wanted to mention that your blog taught be a lot about writing and using modules, and oop. I'll be upgrading to middleclass 4 when I get the time to start working on my game again. I'll report back with results compared to middleclass 3.
Cool

Remember that there's an
Update Guide.
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Mon Jan 30, 2017 6:21 pm
by lukems
kikito wrote:Great news, considering I'm going to use those Rect's a lot!
If you are planning to use it a lot, for intensive calculus etc, I would recommend you to measure how fast it is to not use middleclass at all too. Middleclass (and, in fact, any object-oriented library) is not a good fit for super-tight intensive calculations. For example, I would not use it for vectors or matrixes. For those, I think plain numbers + functions work best. There is no metatables - and there is no tables either. So your intensive code generates as little garbage as possible. That's
what I did for the rectangles in bump.. Vrld has done something for vectors in
vector-light.
I've done two changes on properties.lua to get it working here.
Ok!
(And a minor tweak, comparing things specifically against nil gave it a big performance boost here
That is ... unintuitive. As far as I know,
if x is logically equivalent to
if x ~= nil when x can't be
false. And it seems that the first one should be faster since it is doing less. But that's efficiency for you; one never knows until the test is run.
Good to know, and thanks for all the info and advices!
When I achieve a running'ish state on my project, if things are not fast enough and the Rect looks guilty, I'll check those cases you've provided and try to do it like a pro

I'm hoping, though, that as long as I don't make poor use of them on pathfinding, fov and procedural map generation things are going to be ok (considering that I'm doing a Lua/love2d port of my Python/py-sdl2 thing, every piece of code runs way faster so far).
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Mon Jan 30, 2017 8:16 pm
by DanielPower
My bad, I didn't look at the post date. It turns out I've been using Middleclass 4.0 for a year. Which explains why I didn't know there was ever a global Object class to begin with. I suppose it's time to upgrade to 4.10, I'm only half a year late for that :p
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Tue Jan 31, 2017 3:52 pm
by kikito
DanielPower wrote:It turns out I've been using Middleclass 4.0 for a year

that made me chuckle a little. I don't update middleclass very often now, because I think it is pretty much done. I can try to make it a little bit faster, but that's pretty much it.
Re: [Lib] Middleclass 4.0.0. Object-Orientation for Lua
Posted: Tue Feb 21, 2017 11:48 am
by Zireael
I just realized I am using the outdated Lua module keyword in my project.
I am looking for an OOP implementation that allows multiple inheritance. I looked through git and github wiki and I am not sure whether middleclass supports it or not.