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.