I’m curious as to people’s thoughts concerning mixins for Lucee 5 classes. Being aware of using included templates as mixins is possible, I’m more interested in an object-oriented approach to mixins. My experience with existing other languages/frameworks with mixin capability is limited to PHP Traits, and ExtJS 4+ mixins.
I am somewhat partial to the way PHP does traits, therefore my ideal is very similar to them, with some minor differences. Some initial thoughts on what I think built-in mixin support looks like are as follows:
- Mixins are to be defined as classes. Preferably abstract classes.
- Mixins are loaded into other class definitions using a new keyword. The syntax should follow the form of the short-hand syntax
property
definition for components. - Any constructors are ignored when adding a mixin to a class.
- Classes do not gain any type information from applied mixins.
- Mixin methods are copied into the destination class’ definition.
- Class-defined methods have priority over mixin methods.
- Utilized mixins are to be individually and specifically accessible, in a protected manner (available privately and to sub-classes, but not publicly).
- A class that implements two mixins with the same method name must define its own implementation of that method, otherwise generate a compile-time exception.
An example:
// app/mixins/FearMixin.lucee
abstract class FearMixin {
public function screamIrrationally(message) {
writeoutput(ucase(message) & "!!!");
}
public function shakeHands() {
this.hands.tremble();
this.screamIrrationally("run for your lives");
}
}
// app/mixins/CordialMixin.lucee
abstract class CordialMixin {
public function greetCalmly(message) {
writeoutput("Greetings, I would like to say " & message);
}
public function shakeHands() {
this.hands.rightHand.extend();
this.greetCalmly("put 'er there, partner!");
}
}
class ConflictedIndividual {
use app.mixins.FearMixin fearMixin;
use app.mixins.CordialMixin cordialMixin;
public function shakeHands() {
// access the correct mixin individually based on whether or not the individual is scared at the time.
if (this.isScared) {
fearMixin.shakeHands();
} else {
cordialMixin.shakeHands();
}
}
}
individual = new ConflictedIndividual();
assertFalse(isInstanceOf(individual, "app.mixins.FearMixin"));
I’m putting this here for discussion before creating a proposal issue on Jira. So… thoughts?