to only allow Wheels in the attribute leftRearWheel and to delegate all of Wheel's methods to the leftRearWheel.Class("Car", {
has: {
leftRearWheel: {
init: new Wheel(),
isa: Wheel,
is: rw,
handles: "*"
}
}
})
In other news:
While making method modifiers stackable was really easy for all the other modifiers, I had to roll my own reverse call stack to make it happen with augment.Class("HTMLDoc", {
augment: {
html: function () { return "<html>"+this.INNER()+"</html>" }
}
})
Class("HTMLDocBody", {
isa: HTMLDoc,
augment: {
html: function () { return "<body>"+this.INNER()+"</body>" }
}
})
Class("TPSReport", {
isa: HTMLDocBody,
augment: {
html: function () { return "<h1>TPS-Report</h1>" }
}
})
Class("HardWork", {
meta: Joose.Gears,
has: {
data: {is: rw, init: {}}
},
methods: {
onDoWork: function (result) {
ok(result == 1001, "Gear Worker returns correct result")
}
},
workers: {
doWork: function (start) {
var counter = start;
for(var i = 0; i < 1000; i++) {
counter++
}
return counter
}
}
})
var hw = new HardWork();
hw.doWork(1)
Class("S3", {
isa: S2,
override: {
two: function () {
this.result2 += "3"
this.SUPER();
}
},
before: {
add: function () { this.result += "5" }
}
after: {
add: function () { this.result += "7" }
},
wrap: {
add: function (original) { this.result += "8"; original(); this.result += "9" }
}
})
By using the excplicit override modifier you get access to the overridden method using this.SUPER(). This is basically the same as the wrap modifier, but it keeps the methods signature intact (wrap passes the wrapped function as the first parameter).
Joose now supports two new ways to create Joose.Classes
joosify(MyClass) now turns regular classes into Joose.Clases.
...and you can now use a more JavaScript like Syntax to build Joose.Classes:
Class("Currency", {
does: Eq,
has: ["value", {is: rw}],
methods: {
initialize: function (value) {
this.setValue(value)
},
isEqual: function (cur) {
return this.getValue() == cur.getValue()
}
}
})
Joose the JavaScript implementation of Moose now has Roles.
A direct translation of the Synopsis from Moose::Role looks like this:
Class("Eq", {meta: Joose.Role});
requires("isEqual");
methods({
notEqual: function (para) {
return !this.isEqual(para)
}
})
Class("Currency");
does(Eq)
has("value", {is: rw})
methods({
initialize: function (value) {
this.setValue(value)
},
isEqual: function (cur) {
return this.getValue() == cur.getValue()
}
})
check()
The check() makes a "compile time" check of the role requirements. This might later be implemented as an onload-event in browsers.
Joose.Roles are themselves implemented as Joose.Classes. The source looks like this:
Class("Joose.Role");
isa(Joose.Class);
has("requiresMethodNames")
methods({
initialize: function () {
this.name = "Joose.Role"
this.requiresMethodNames = [];
},
addRequirement: function (methodName) {
this.requiresMethodNames.push(methodName)
},
exportTo: function (classObject) {
classObject.meta.importMethods(this.getClassObject())
},
hasRequiredMethods: function (classObject) {
var complete = true
this.requiresMethodNames.each(function (value) {
var found = classObject.meta.can(value)
if(!found) {
complete = false
}
})
return complete
},
isImplementedBy: function (classObject) {
var complete = this.hasRequiredMethods(classObject);
if(complete) {
complete = this.implementsMyMethods(classObject);
}
return complete
}
})
This must have been done before, but it was fun anyway. I have written a partial implementation of Moose (and Class::MOP) in JavaScript. It's called Joose. It is self-hosting, so you can write meta classes in Joose and you get some of the syntactic sugar from Moose.
A typical example would be:
Class("Animal");
methods({
multiply: function () { return this.meta.instantiate() }
})
Class("Cat");
isa(Animal)
methods({
likes: function () { return "fish" }
})
Class("Dog");
isa(Animal)
has("owner", {is: rw})
methods({
balksAt: function () { return this.owner },
hates: function () { Cat }
})
ok(Cat.meta.isa(Animal), "Cats are animals");
ok(Dog.meta.isa(Animal), "Dogs are animals too");
ok(!Animal.meta.isa(Cat), "Not all animals are cats")
ok(new Cat().likes() == "fish", "Cats like fish");
ok(new Cat().multiply().likes() == "fish", "Cat babies like fish")
ok(new Cat().multiply().meta.isa(Cat), "Cat babies are Cats")
There seems to be some interest in xssinterface in the javascript community so I put it up as a project on Google Code.
Meanwhile I implemented the usage of the new HTML 5 postMessage() method that implements the same behavior for new browsers where available.
Does anybody here have a clue about p3p xml privacy policies? Looks like the worst, over engineered spec since SOAP WS-*