Hi Everyone,
I've been playing with the runtime again...
Nicolas suggested the stuff I wrote on Friday could be used for
mixins, but it seemed a bit clunky to me, so I've written a category
on NSObject that implements mixins without needing a modified runtime
(although, for now, it does require the GNU runtime; the same thing
would be possible with the Apple runtime, and I may port it later).
This is based, loosely, on the work done by the Strongtalk team at Sun.
Mixins, in this implementation, are declared as classes at compile
time, and then composed with other classes at runtime. This means
that they can do anything classes can do, including:
- Send messages to super.
- Access instance variables.
When composing two classes, you simply do:
[class mixInClass:mixin];
This will throw an exception if:
- The mixin's ivars do not match the classes (the class can have
more, but it must have all of the ones the mixin has). The names
don't have to match, but the types do (would it be useful if the
names did?)
- The class can not implement any of the methods in the mixin with a
different type signature to the implementation in the mixin. For
example, if your class implemented:
- (void) append:(id) anObject;
and your mixin implemented:
- (void) append:(int) anInt;
An exception would be raised. Note that the runtime does not store
any information for objects beyond the fact that they are objects,
and so it is possible to have type inconsistencies arising from that
(e.g. one expects an NSString as a parameter and the other expects an
NSNumber). If this happens, a runtime exception will be raised when
the method tries to do something to the parameter object that it
doesn't understand.
As an example, this is the program I was using to test the
implementation:
@interface Test : NSObject {
}
- (void) test;
@end
@implementation Test
- (void) test
{
NSLog(@"Test called!");
}
@end
int main(void)
{
[NSAutoreleasePool new];
[NSObject mixInClass:[Test class]];
id testObject = [NSObject new];
[testObject test]; return 0;
}
When run, this gives the following output:
2007-10-17 17:15:39.404 test[2457] Test called!
If I add the following method:
- (int) retain
{
return [self retainCount];
}
The output becomes:
./obj/test: Uncaught exception MixinMethodTypeMismatchException,
reason: Method types of class NSObject do not match those of mixin Test.
Adding an instance variable will also causes an exception to be thrown.
Mixins can directly access instance variables, as long as they are
defined in the class implementing the mixin. A good way of doing
this is to make the mixin a subclass of a class that all of the
classes you are likely to want to apply it to inherit from.
Note: Use of mixins, unlike prototypes, imposes no runtime overhead.
David
_______________________________________________
Etoile-dev mailing list
[email protected]
https://mail.gna.org/listinfo/etoile-dev