Underoop
A OOP Library for Underscore.js inspired by Ruby
Install / Use
/learn @ShiftSpace/UnderoopREADME
h1. Introduction to Underoop.js
Underoop.js is a Underscore.js mixin that adds some handy functions for OOP style development. This style of development is particulary useful when bulding extensible, loosely coupled components that are consistently and logically structured around some data. I also wanted to create a set of extensions that integrate well with Underscore's handy functional operations on JavaScript Objects and Arrays.
h2. Defining new Classes
Often you want OOP class-like things but writing your objects in the following manner is tedious:
<pre> var MyClass = function() { this.foo = "foo"; this.bar = "bar"; }; MyClass.prototype.baz = function() { ... } MyClass.prototype.woz = function() { ... } </pre>Using Underoop.js you can instead write the following:
<pre> var MyClass = _.Class({ initialize: function() { this.foo = "foo"; this.bar = "bar"; }, baz: function () { }, woz: function() { } }); </pre>h2. Defining Modules
Often you'll have a chunk of functionality that does not belong to a particular class. You can define a set of methods like so:
<pre> var Events = _.Module({ addEvent: function(type, fn) { ... }, removeEvent: function(type, fn) { ... }, removeEvents: function(type) { ... }, fireEvent: function(type, data) { ... } }); </pre>And "mixin" in this functionality easily:
<pre> var Foo = _.Class({ includes: [Events], initialize: function () { ... } }); </pre>Rubyists will find this familiar.
h2. Messaging
Selectors are pretty useful, especially at cutting down the amount of typing. All methods of a Class are added as helper functins to an object <code>_sel</code> so you can use them with Underscore's excellent interfaces to the JavaScript collections.
<pre> var Foo = _.Class({ initialize: function(z) { this.z = z; }, add: function(x, y) { return [x, y, this.z].join(""); } }); var Bar = _.Class({ initialize: function(z) { this.z = z; }, add: function(x, y) { return x + y + this.z; } }); var a = new Foo("cool!"); var b = new Bar(6); _([a, b]).map(_sel.add(4, 5)); </pre>Take note that for any method <code>foo</code> you will need to write <code>_sel.foo()</code> even if it takes no arguments.
h2. Inheritance
Underoop does not support inheritance. Inheritance breaks miserably under AJAX requests without a lot of ugly hacks. After many years of OOP I've come to the conclusion that inheritance is a bug. Clojurians and Haskellers agree. Use Modules.
h2. Caveats
Name clashes are always a concern between Class method names, Class instance vars, Module method names, and Module instance vars. Underoop can't solve these problems without adding a lot of incidental complexity for you and myself. However JavaScript private scope, lookup tables, and Underscore's excellent <code>_.unqiueId</code> can work wonders for your particular usecase ;)
h2. Provided Mixins
Underoop.js comes with two convenient modules. Events allows setting up custom events between objects. The other, Options, allows you to to parse data attributes on elements to passed onto instance constructors. This makes it easy to have your script automatically instantiate widgets from markup.
<pre> <div data-your-ns-prop-a="Asset" data-your-ns-prop-b="<%=@community.asset_url%>" data-your-ns-prop-c="<%=@community.taxonomy%>"> </div> </pre>h2. Props
The design of this library is drawn heavily from MooTools. If you work in an environment where you can control all of the JS I heartily recommend it. Otherwise jQuery + Underscore + Underoop will have to do.
