middleclass & extras: middleclass 3.0 is out!

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
tentus
Inner party member
Posts: 1060
Joined: Sun Oct 31, 2010 7:56 pm
Location: Appalachia
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by tentus »

zac352 wrote:I'm consistent. :P
Then that's fine. :) As long as colour is always spelled with a u, there's no problem.
Kurosuke needs beta testers
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by Jasoco »

It should accept both spellings as correct. That's the way it should be. Color, colour, doesn't matter.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by kikito »

Jasoco wrote:It should accept both spellings as correct. That's the way it should be. Color, colour, doesn't matter.
Well, I don't like that idea because someone could say "hey, it should also include iniciar and intialisieren". Once you accept 2 languages, what stops you from accepting several more? You have do draw the line somewhere.

Note though that implementing that kind of thing safely is actually quite trivial:

Code: Select all

function Object.initialise(...)
  Object.initialize(...)
end
But I don't recommend doing that.

Besides, the middleclass-extras module assumes that it is called initialize. If it's called anything else, chances are that some things will not work.

Going back on-topic, I've implemented the changes Thelinx requested. It should be now safe to include lib.middleclass.init (or any other folder that your heart so desires). Just be consistent; don't use require 'middleclass' in some places and require 'lib.middleclass' in others. Otherwise, weird things may happen.

Regards!
When I write def I mean function.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by kikito »

I've done it!

After lots of code torturing, I finally was able to create a satisfactory way of doing __index on classes: Indexable.lua is the new middleclass-extras module in charge of that.

Basic usage:

Code: Select all

  require 'middleclass' -- or similar
  require 'middleclass-extras.init' -- or 'middleclass-extras'

  MyClass = class('MyClass'):include(Indexable)
  function MyClass:initialize(a,b,c)
    super.initialize(self)
    self.a, self.b, self.c = a,b,c
  end
  
  function MyClass:index(name) -- attention! index, not __index !
    return 'could not find ' .. tostring(name)
  end
  
  local x = MyClass:new(1,2,3)
  
  print(x.a) -- 1
  print(x.b) -- 2
  print(x.c) -- 3
  print(x.d) -- 'could not find d'
It is not fully tested yet - I'm not sure how whether it'll play nice with Stateful, for example. But unit tests pass successfully.

Thelinx, feel free to give it a try.

Kudos to Mud (Mud?) who helped me out in deciding how to implement this.

Oh, also, I've released a new version of middleclass (We're now at 1.2).
  • This new version is backwards-compatible with 1.1
  • But it is smaller, slightly faster, and more beautiful.
  • It also includes thelinx's patch for making it more 'folder-aware'.
  • Finally, this new version throws an error if you try to create an __index function on a class, and advices you to use Indexable + index instead
When I write def I mean function.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by kikito »

Small update, and announcement!

The small update is that I've been able to fix my first publicly reported bugs - one on middleclass itself, and the other on middleclass-extras. None of them were terribly critical (I didn't even bother changing the version number), and reflected edge cases I didn't think about. But the second one took me 2 weeks to finally fix!

The announcement is the following: a backwards-breaking change is approaching. And it is pretty significant.

Concretely, I'm thinking about changing the super syntax.

Current syntax is this:

Code: Select all

super.initialize(self, foo, bar, baz)
The future syntax migth look similar to this:

Code: Select all

self.super:initialize(foo, bar, baz) -- I still have to iron out some details, though
There are several reasons for this change.
  • The first one is merely aesthetic. I never liked the old syntax very much. But I couldn't think of another.
  • The second one is that I need to use setfenv and getfenv for it to work. These two functions will be deprecated on the next version of Lua. So they are better left out.
  • The last reason is probably the most important one: the new syntax will make middleclass faster. I don't know exactly how much faster, but in some edge cases (simple functions with little operations but lots of variables) it might increase speed by a twofold.
To me, the last point is the most important one (boring explanation follows).

What happens right now is that getfenv/setfenv put a "phantom" table between _G and the methods. It's on this intermediate table where the current 'super' resides. This works fine if you want to use 'super', but the intermediate table uses __index to get to _G. This means that all the access to _G from inside class methods currently take 2 redirections instead of one.

So, despite what I said in another post, currently middleclass is slower than going classes "the manual way", setting metatables directly. All due to a poorly designed syntax!

With the future notation, middleclass will be as efficient as settings the metatables directly. And the syntax will be a bit nicer.

I want to apologize in advance for the inconveniences this could cause.

Regards!
When I write def I mean function.
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Milwaukee, WI
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by TechnoCat »

Hooray. Updates!
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by BlackBulletIV »

A shame the super syntax has to change, I like it how it is... but you have good reason to change it; if it makes things faster and puts it inline with the next version of Lua, you can't argue with that.

EDIT: Oh hang on, I just noticed that I no longer have pass in self to super methods. I like that!
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Milwaukee, WI
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by TechnoCat »

Just started using mixin after reading http://love2d.org/forums/viewtopic.php? ... =10#p25716

I can't believe I never used mixins before. This is exactly what I was currently looking for on my current project. I was trying to do confusing multi-inheritance classes, but just importing commonly used functions is much more suitable for this task. Now the minigame writers will just do MiniGameClass:include('MiniGameFunctions') and directly call the methods instead of using super.method, and even it would seem super.super.method. Then on top of that, I can have a few different specialised mixins they can choose to include such as platformer physics and space physics.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by kikito »

I'm glad they helped you out! middleclass.extras is completely mixin-oriented.

If you are curious, I "borrowed" the idea of mixins from ruby, although my implementation is quite crude and simple. Java's interfaces always bugged me ("why can't I just have a default implementation???"). When I saw them on ruby, I though to myself "finally, some sanity!"

In my mind, classes have 'is a' relations with instances (jimmy is a Person) while mixins have 'can' relations (jimmy can Jump).

The idea of including parameters when including a mixin is all mine :P AFAIK. Although I still haven't needed it yet.
When I write def I mean function.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: middleclass & middleclass-extras: OOP for LUA

Post by BlackBulletIV »

kikito wrote:"why can't I just have a default implementation???"
In other languages that are at least similarish to Java (like ActionScript, and C++) you can have abstract base classes (Java has these as well I think) to fix the problem; but they're only in the line of single inheritance. I think the perfect mix is having single inheritance, mixins, and the possibility of abstract mixins and base classes; that would be sweeeet.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 0 guests