JS.Class 2.0, now with even more Ruby-ness

A couple of months ago, I began a complete rewrite of JS.Class, as I’d become dissatisfied at some of its incompatibilities with Ruby, specifically with respect to module support. The 1.x series supported mixins in a reasonable way, but would not allow callSuper() to call methods from mixins. There were also a number of issues with the way extend and include work, which would surprise anyone expecting Ruby-like behaviour. In short, this particular abstraction was a bit too leaky.

The only way to get around this was a complete rewrite with Module right at the core, rather than having it tacked onto a fundamentally Class-based system. (In Ruby, Class inherits from Module, and both are classes.) The end result is that JS.Class 2.0 is much more Ruby-like: its method lookup rules are identical, and its internals are more Ruby-like too – JS.Class is a subclass of JS.Module, objects have eigenclasses, you can inspect method lookup results at runtime, and all sorts of other craziness. All these enhancements are hidden from you most of the time, but the extra metaprogrammability is allowing me to do some cool things – at the moment I’m working on a ‘compiler’ that will generate code for your classes that doesn’t depend on JS.Class, so you can use the library as a build tool rather than as a runtime dependency.

On top of these mostly invisible changes, there are three newcomers to the standard library: Package, Set and StackTrace. Package gives you the equivalent of Ruby’s require statement so you can declare URLs for various objects in your code, and lazy-load those objects (including dependencies) at runtime. Set implements a collection of unique objects, with support for custom object comparison. It has a subclass SortedSet that keeps its members in sort order, making searches faster – I’ve benchmarked it against KevLin’s red black tree library and its performance is roughly the same for insertion and searching. StackTrace is a debugging tool that allows classes to log all their method calls to the Firebug console, along with arguments, return values and stack level. This module was made possible by the new ability to redefine how method definition works in JS.Class 2.0.

Enough waffle from me: go and download it and play around. It is largely backward compatible with 1.x, but there are some small easily fixable cases where it may break old code – see the upgrade notes for more information.

If you’ve enjoyed this article, you might enjoy my recently published book JavaScript Testing Recipes. It’s full of simple techniques for writing modular, maintainable JavaScript apps in the browser and on the server.