Monday, July 28, 2008

Total JavaScript Makeover

The new before and after page on the Joose wiki shows some simple examples of JavaScript code with and without Joose.
Obviously anybody, who has written more than twenty lines of JS in his/her life, either uses a class builder or at least utility functions to do these things.
Among those features of Joose that you won't find in your every day JS class builder are (all fancy meta stuff intentionally left out):
  • Automatic generation of accessor methods for attributes
  • Automatic generation of object initialization methods
  • Method modifiers (before, after, etc.)
  • Overriding of super class methods with access to the overriden method from the super class
  • Automatic serialization and deserialization of your (nested) objects to JSON (Joose.Storage)

Talking about Joose

Joose now has a mailing list. Feel free to join.

Getting Started Guide for Joose

There is now a getting started guide for Joose.

Friday, July 25, 2008

Version 0.99 of Joose released

We just released version 0.99 of Joose.
Download it here.

Joose is a self-hosting meta object system for JavaScript with support for classes, inheritance, mixins, traits, method modifiers and more. It makes object-oriented programming with JavaScript easy, declarative and very productive. The Joose meta-object system is multi-paradigm. It supports class-based and prototype-based programming styles as well as class-based inheritance and role-based extention.
The Joose framework has been successfully used in multiple production systems for four months now and has been proven to be very stable. Joose is being tested using an automated unit-test suite that is being run in all major browsers (Firefox, IE, Safari, Opera).

New stuff in Joose 0.99

  • Method modifiers can be used in roles
  • Joose.Storage now preserves object identities across serializations and deserializations. Joose.Storage is a role for automatic JSON stringification and restorations of Joose objects that is very powerful and easy to use. I'll write about it in another article.
  • Applying roles to instances no longer detaches the meta class for every role. Once is enough.
  • Joose.Gears now supports AJAX-Requests that are performent through Gears if available. This greatly reduces stress for applications that do a lot of polling
  • Various bug fixes
  • Intesive profiling and speed improvements
  • Pretty much all anonymous functions in Joose now have a name which makes debugging and profiling with firebug much easier.

What's next:

  • This version of Joose will be released as 1.0 when the documentation is ready
  • Specialized Plugin-Objects
  • Types and Type-Coercions (some support is already in Joose, see tests/16_types.js
Have fun with Joose!

Saturday, July 19, 2008

Class extention with roles and method modifiers

While working on blok I introduced a new feature to Joose that has proven to be a very powerful programming technique: Method modifiers used in roles.

Let me start with a quick introduction to those two concepts:

Method modifiers are declarative approach to JavaScript method wrapping techniques. They allow you to do stuff before or after a method is executed or to override a method and only call the method in the super class "on demand" using this.SUPER(). In the Joose cookbook a before method modifier is used to adjust a bank account balance using an overdraft account if neccessary:
Class("CheckingAccount", {
isa
: m.Account,
has
: {
overdraftAccount
: {
isa
: m.Account,
is: rw
}
},
before
: {
withdraw
: function (amount) {
var overdraftAmount = amount - this.getBalance()

if(this.overdraftAccount && overdraftAmount > 0) {
this.overdraftAccount.withdraw(overdraftAmount);
this.deposit(overdraftAmount);
}
}
}
})
Roles are a mixture between Java-Interfaces and and Ruby Mixins. They were originally called Traits but we like Role better :) They require that a class that implements them provides a set of methods but in contrast to traditional interfaces they may also export methods into the classes that implement them. Those methods may only use other methods provided or required by the role. That way a role can guarantee that the functionality it provides actually works in the destination class. A class that does a role may of course always choose to override methods provided by the role. This way roles give you all the power of multiple inheritance without the problems of mi.

Now to the real topic of this post: Method modifiers in roles.
Using method modifiers in roles creates a very natural and declarative way of solving a problem that is traditionally tackled with the decorator pattern:

(Dramatized) Java:
Window win = new ScrollingWindowDecorator(
new TabbedWindow
Decorator(
new ResizableWindow
Decorator(
new DraggableWindow
Decorator(
new Window("Window Name")))))
The decorator allows the dynamic composition of functionality by giving each decorator the chance to modify the behavior of the object when a method is called. Besides looking like Lisp because of all the )))) the decorator has one primary problem (or features depending on the view point): When window calls a method on itself, none of the methods of any of the decorator will be called.

Method modifying roles to the rescue. Consider this example: We want to model people who vary in their behavior when they say hello to somebody. Some people introduce themselves, some people are shy, some people stutter, all people say hello. The person class in Joose is easy:
Class("Person", {
methods: {
sayHello: function () {
print("Hello!")
}
}
})
The sayHello method prints "Hello!" when you call it. Now we use roles and method modifiers to attach extra functionality to the sayHello method. Lets start with the shy person:
Role("ShyPerson", {
before: {
sayHello: function () {
print("May I talk to you?")
}
}
})
Everytime before the ShyPerson says hello, she aks whether she may talk to you. Introductions follow the same principle:
Role("Introduction", {
after: {
sayHello: function () {
print("I am a Joose user.")
}
}
})
In our example people who stutter say "Stutter" before they say hello and then say everything twice. This example shows the implementation using the around and override method modifiers:
Role("Stuttering", {
around: {
// say it twice
sayHello: function (orig) {
orig()
orig()
}
},
override: {
// say Stutter and and say what was defined before
sayHello: function () {
print("Stutter")
this.SUPER()
}
}
})
Now, we'll define classes for two different persons with different behaviors:
Class("Eve", {
isa: Person,
does: [
Introduction,
ShyPerson
]
})

Class("Adam", {
isa: Person,
does: [
Introduction,
ShyPerson,
Stuttering
]
})
The does-keyword in the class declaration tells Joose that this class implements roles that follow in the declaration. So now Eve introduces herself and is shy. Adam has the same attributes but also stutters. Should Eve ever start to stutter, we can, of course, always later apply the Stuttering role to eve's instances: Stuttering.meta.apply(eve)

When you use the classes it looks like this (print is defined as somehow printing its arguments and attaching a new line):
var eve = new Eve();
eve.sayHello() // prints May I talk to you?\nHello!\nI am a Joose user.\n

var adam = new Adam();
adam.sayHello() // prints Stutter\nMay I talk to you?\nHello!\nI am a Joose user.\nMay I talk to you?\nHello!\nI am a Joose user.\n
Conclusion:
The above example shows how roles can be used to nicely attach extra functionality to classes using method modifiers. This pattern is especially useful if you need to augment a certain set of functionality without totally replacing the original methods which is a common phenomenon when you deal with GUI elements.

Improvements to Joose

Over the last couple of weeks most development time went into blok which is testing Joose in all possible directions which in turn leads to improvements to Joose:
  • Joose.Storage now preserves object identities across serializations and deserializations. Joose.Storage is a role for automatic JSON stringification and restorations of Joose objects that is very powerful and easy to use. I'll write about it in another article.
  • Applying roles to instances no longer detaches the meta class for every role. Once is enough.
  • Joose.Gears now supports AJAX-Requests that are performent through Gears if available. This greatly reduces stress for applications that do a lot of polling
  • Various bug fixes
  • Intesive profiling and speed improvements
  • Pretty much all anonymous functions in Joose now have a name which makes debugging and profiling with firebug much easier.
The by far biggest feature is method modifiers in roles. This is one of the most powerful constructs for in recent programming history and I'll write about it in another article :)

Wednesday, July 9, 2008

blok documents as a Google Gadget

Blok documents can now be embedded as a Google Gadget (as can thus be embedded into google spreadsheets). The feature is highly experimental right now, but will get better. If you have a document with the url http://blok.appspot.com/?id=efdc360d2dd2b3f0ed24b156e4751bb035fee0a4, change this to http://blok.appspot.com/gadget.xml?id=efdc360d2dd2b3f0ed24b156e4751bb035fee0a4 and you can embed the url as a google gadget.

You can check out an example document at this url: http://spreadsheets.google.com/pub?key=p8nd1kNNlWNuTmZ3XLUADEg

Sunday, July 6, 2008

blok now uses Google Gears where available

blok now uses the Google Gears HttpRequest API to make the synchronization calls to the server if gears is installed on the client. This makes the GUI feel a little more responsive. Next up is using Gears to offload the rest of the syncing work (primarily JSON stringification and parsing) that can be done in gears (everything that does not need to manipulate the DOM.
Joose supports a transparent method to offload hard work into Gears workers that was even talked about on the Google Gears blog. While the method used to be rather basic I'm enhancing it now so that you can use the Timer and HttpRequest api transparently in your code without having to care about whether google gears is actually available (work is done in the main thread if gears is not installed).

Friday, July 4, 2008

Changed Repository to Google Code

I moved the Joose SVN repository back to the Joose's Google Code site.
Joose used to live in the Moose repository which was great but didn't have a great function to view the source code without checking it out of the repository.
I'd recommend looking at the class that represents the rectangle shapes in the blok application. It really shows how roles can be used as a very flexible extention mechanism.

Thursday, July 3, 2008

Undo

blok now does undo :) (Ctrl + z (Or the command key on the mac))

Wednesday, July 2, 2008

More Features for blok

I have continued to work on blok and added a lot of features. The most significant are:
  • You can now select two shapes (use the shift key to select the second one) and connect them using lines
  • When you select a shape you will see a properties panel on the lower side of your screen that lets you edit all the shapes's properties
  • Some regular keyboard shortcuts work: copy (Command/Ctrl c), paste(v), delete (del or remove) (Reminds me I should add cut :), select all (a)
  • Login is no longer required to play with blok. I'll add optional logins later.
  • blok somewhat works in IE7 (If I haven't broken it since Monday)
I probably forgot a lot of stuff, but that should be the most important stuff.