Monday, March 31, 2008

detach

Als Joose.Objects now have a detach method. After you call detach on an object it gets its own meta class. Calling methods like addMethod on the object's meta object will whus only effect the obejct itself (but not it's former class)

Friday, March 28, 2008

Joose on the Google Gears blog

Dion Almaer has written a nice article about Joose on the Google Gears blog.

If you want to get into programming with Joose, porting the new proof-of-concept class browser to a nice toolkit like Dojo might be a good starting point.

Thursday, March 27, 2008

Class Browser

Joose now ha a new example: A class browser that shows the current active classes. You can try it out here.

Wednesday, March 26, 2008

Attribute Meta Classes

Attributes now have their own meta class in Joose. Support for attribute traits is currently quite limited, but you can say:
Class("Car", {
has: {
leftRearWheel: {
init: new Wheel(),
isa: Wheel,
is: rw,
handles: "*"
}
}
})
to only allow Wheels in the attribute leftRearWheel and to delegate all of Wheel's methods to the leftRearWheel.

In other news:

  • Joose is now hosted in the Moose svn
  • Joose now supports the Moose JSON Storage format and allows round trips between Moose and Joose (at least for basic tests)
  • Joose now works in IE and Opera
  • Joose now supports class methods

Saturday, March 22, 2008

Joose can write TPS-Reports

While advancing at least two computer science zen levels I augmented my brain enough to implement the augment method modifier in Joose.

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>" }
}
})

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.

Friday, March 21, 2008

Joose on Gears

You can now automatically execute methods of a Joose.Class in a different thread using Google Gears. All you need to do is use the meta class Joose.Gears and add a worker method. All the Gears-Interfacing is handled for you. If Gears is not present, the worker is executed in the main thread. The workers result will be sent to a method called "on".ucfirst($worker_name) if available:

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)

Joose now has method modifies

You can now use the following method modifiers in Joose:

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).

Wednesday, March 19, 2008

New Class-Builder Syntax for Joose

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()
}
}
})

Wednesday, March 5, 2008

Joose has Roles / Traits

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
}
})

Tuesday, March 4, 2008

Moose in JavaScript

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")