Page Contents
Basic requirements of an object/class structure
- Single Inheritance
- Interfaces
- Casting up/down the hierarchy (really just conformance checking)
- Ability to query the presence of given interfaces or parent classes
- Everything inherits from a single Class
- Classes need some way to handle private data/methods (perhaps via hiding)
- Providing for operator overloading by generic metamethod application?
How it might look?
Some examples of how it might look to use:
Top level class
Class "Counter" {
Constructor = function(obj,start)
obj.count = start or 0;
end,
Increment = function(obj) obj.count = obj.count + 1; end,
GetCount = function(obj) return obj.count; end
}
ctr = New "Counter" ();
-- Would ctr = New(Counter); be nicer?
-- Or perhaps ctr = Counter.New()
ctr.Increment();
-- should work just the same as:
ctr:Increment()
-- That should be done by some careful metamethods and intervening functions
Subclasses?
Class "CountByTwo" "Counter" {
Increment = function(obj) obj.count = obj.count + 1; end,
IncrementOther = function(obj) obj.parentcall.Increment(); obj.parentcall.Increment(); end,
}
counterfactory = New "CountByTwo";
ctr = counterfactory();
ctr2 = counterfactory();
Checking Types
if IsA "Counter" (ctr) then print "ctr is a Counter, or subclass thereof" end if IsA( "Counter", ctr ) then print "another way but ctr is still a Counter" end if Implements "Serialisable" (ctr) then print "ctr can be serialised" end if ctr.Implements "Serialisable" then print "Reserved method Implements indicates serialisability" end
Comments:
- I am moving away from using the Luabind-oo system to my own for performance reasons, but i'm kinda emulating their syntax some as i found it nicer than others i've seen:
class 'object' function object:__init( value ) self._value = value or 0 end function object:do_somthing( value ) self._value = self._value + value end class ( 'object2', object ) function object2:__init( value ) self.super.__init( self, value ) -- call base constructor or not self._value = 2 end function object2:do_somthing( value ) value = value + 100 self.super.do_somthing( self, value ) end -- create an instance... notice no 'new' syntax. -- Why have new when there is no delete. local my_object = object2( 100 ) my_object:do_somthing( 2 ) -- must use : for non-static functions!
- This seemed cleaner and more familiar syntax than trying to do...
my_function = function () blah end, my_function2 = function () blah blah end,
- -- TomSpilman?
- Also, without considering the way you're implementing 'self.super' I'd like to comment that the moment you have something inheriting from object2 you run the risk of having a nasty infinite loop with supercalls. There's a reason my parentcall function does scary things with getinfo() do be careful.
- I considered that kind of syntax, and while I certainly prefer the basic layout, I don't like creating top level variables implicitly (I.E. what
class 'foo';does). I'm currently pondering whether the answer is to work on the parser to allow the following to be valid:
footable = {
function bar(self,n)
...
end
}