[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RES: Standard Object Reflection (was Re: OOP in daydream...)
- From: André de Leiradella <leiradella@...>
- Date: Wed, 19 Jan 2005 14:37:39 -0300
lua-bounces@bazar2.conectiva.com.br wrote:
> Although there's more than one way to skin the OOP
> cat in Lua, it would be useful to have some conventions.
>
> For example, consider a class browser. Such code can't
> even assume that the methods are stashed in the
> object's metatable! One solution is to expect class
> systems to export some standard functions:
>
> 1) _classes_defined
> A user-defined iterator for finding all the classes defined
> in the system. (If it isn't defined, we can probably cope
> by browsing the global environment recursively)
>
> 2) _base
> Any table intended to be used as a class will export
> a method _base, which may of course return nil.
>
> 3) _methods
> Any class must define this iterator, which gives the
> available methods; from there, the debug interface
> could give us where they're physically defined.
> (Whether this gives _all_ inherited methods, or just methods defined
> by this class, is an interesting question. I'd say this should be an
> option)
>
> So no matter how one sets up one's object system,
> such a convention would allow general tools
> to be built that don't require detailed knowledge
> of the object system.
>
> steve d.
I like your idea. Class systems could be packages that follow some
conventions to allow getting information of a particular system and to
make interoperability possible (e.g. using one class system to subclass
a class of another class system).
A class system package could return a table with some defined functions:
----------------8<----------------
local function _classes_defined()
-- returns an iterator that will return
-- each class defined in this system
end
local function _super_of(class)
-- returns an iterator that will return
-- each super class of the defined class
-- (makes multiple inheritance possible)
end
local function _methods_of(class, inherited)
-- returns an iterator that will return
-- each method of the class, climbing up
-- the inheritance tree of the class if
-- the parameter inherited is true
end
local package = {
classes_defined = _classes_defined,
super_of = _super_of,
methods_of = _methods_of
}
return package
----------------8<----------------
To make interoperability possible, some other functions have to be
defined:
----------------8<----------------
local function _inherited_method(class, method)
-- returns a function that is the given
-- method of some super class of class
-- or nil if no such method exists
end
local function _new(class, constructor, ...)
-- returns a new instance of class calling
-- the provided constructor with the
-- ... arguments or nil if the class
-- wasn't defined in this system
end
local package = {
classes_defined = _classes_defined,
super_of = _super_of,
methods_of = _methods_of,
inherited_method = _inherited_method,
new = _new
}
return package
----------------8<----------------
Also to make interoperability possible, each class must have a "private"
_PACKAGE field which points to the package table of the class system
where the class was defined, and each instance must have a "private"
_CLASS field which points to the class it's an instance of.
Helper functions can be written to make life easier when using
simultaneous class systems:
----------------8<----------------
function new(class, constructor, ...)
return class._PACKAGE.new(class, constructor, ...)
function inherited(self, method, ...)
local func = self._CLASS._PACKAGE.inherited_method(self._CLASS,
method)
return func(self, ...)
end
-- in my class system I call "class" to
-- define a new class, passing it's super
-- classes as arguments
MirroredSurface = class(Surface)
-- override a constructor
function MirroredSurface:load(fileName)
-- call the inherited constructor
inherited(self, "load", fileName)
-- call a function from a package that
-- will mirror the image, surface is
-- an userdata created by the inherited
-- constructor
SDL_gfx.mirror(self.surface)
end
Screen = new(Screen, 'init', 640, 480)
background = new(Surface, 'load', 'background.png')
joeLeft = new(Surface, 'load', 'joe.png')
joeRight = new(MirroredSurface, 'load', 'joe.png')
background:blit(screen, 0, 0)
joeLeft:blit(screen, 100, 100)
Screen:flip()
----------------8<----------------
Assumptions
-----------
. Multiple constructors can be defined
As Lua won't support method overloading, I think we should have multiple
constructors.
. Multiple inheritance can be used
Having super_of returning an iterator gives the programmer the choice of
having multiple inheritance or not, I do have in my class system to
mimic Java's interfaces.
. Methods must be called with ':'
Class system implementors must at least agree with this, it'll be
terrible for the programmer to have to remember to use ':' with some
instances and '.' with anothers.
. Properties must be accessed with '.'
Is there another way of doing it? Seriously, maybe all objects should be
opaque, and getter/setter methods provided. But this will increase
typing.
What I like
-----------
. Having classes from various class systems working toghether
What I don't like
-----------------
. The syntax to call constructors
Maybe lhf's token filter can help with that.
. The syntax to call inherited methods
Likewise.
. The repeated typing of 'self'
This has already been discussed, and today I found myself happily typing
'this.foo', 'this.bar' on class constructors of a Java application I'm
working on because I like constructor parameters to match the member
variables. I don't use 'this' in other methods too much though. I just
like I could have the option to use it or not... (no replies necessary).
. This whole class system interoperability thing
This whole thing could be avoided if Lua had it in the core, but I can't
ask for that after asking for the package system to be *out* of the core
:)
Conclusion
----------
It seems to me that class systems interoperability is possible, and I
think the community should agree on some standard (like the one proposed
here) before that package system comes and a lot of packages are made
with incompatible class systems.
Please don't try to check my code, that's quite a long time I don't code
in Lua (finishing my master degree's thesis). Please also forgive me if
I forgot something important, or if the proposal is totally useless...
Regards,
Andre de Leiradella