Skip to content

Commit

Permalink
* datatype.js: latest
Browse files Browse the repository at this point in the history
  • Loading branch information
swannodette committed May 19, 2010
1 parent e483e6b commit 494ffbf
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 37 deletions.
34 changes: 19 additions & 15 deletions datatype.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
(function() {

var multiMap = {};
var root = this;
root._sel = {};

function Type() {};
function Protocol() {};

Expand All @@ -9,20 +11,6 @@
return _(x.protocols).indexOf(protocol) != -1;
},

Multi: function(name, type, fn) {
if(_.isUndefined(multiMap[name])) {
var dispatchTable = {},
dispatcher = {};
multiMap[name] = dispatchTable;
dispatcher[name] = function(instance) {
var rest = _.rest(arguments);
return multiMap[name][instance.name].apply(instance, rest);
};
_.mixin(dispatcher);
}
multiMap[name][type.name] = fn;
},

isProtocol: function() {
return x instanceof Protocol;
},
Expand Down Expand Up @@ -65,9 +53,25 @@
klass.prototype = new Type();
klass.prototype.type = klass;
klass.prototype.protocols = klass.protocols = protocols;

_(obj).each(function(v, k) {
klass.prototype[k] = v;
if(_.isUndefined(_sel[k])) {
_sel[k] = function() {
var args = arguments;
return function(x) {
var result;
try{
result = x[k].apply(x, args);
} catch (err) {
throw Error([x.name, "does not implement", k, "or signature does not match"].join(" "));
}
return result;
};
};
}
});

return klass;
}
});
Expand Down
43 changes: 21 additions & 22 deletions readme.textile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ MyClass.prototype.woz = function() {
Using datatype.js you can instead write the following:

<pre>
var MyClass = _.datatype({
var MyClass = _.Type({
initialize: function() {
this.foo = "foo";
this.bar = "bar";
Expand All @@ -41,7 +41,7 @@ h2. Protocols
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 = _.protocol({
var Events = _.Protocol({
addEvent: function(type, fn) { ... },
removeEvent: function(type, fn) { ... },
removeEvents: function(type) { ... },
Expand All @@ -52,7 +52,7 @@ var Events = _.protocol({
And "mixin" in this functionality easily:

<pre>
var Foo = _.datatype({
var Foo = _.Type({
protocols: [Events],
intialize: function () {
...
Expand All @@ -62,29 +62,28 @@ var Foo = _.datatype({

h2. Polymorphism

datatype.js doesn't support datatype inheritance of any kind. However it is sometimes useful to reuse a name. For this purpose there is <code>_.multi</code>. You can use this like so:
Being able to package up a message is pretty useful, especially at cutting down the amount of typing that you have to do. All methods of a Type are added to <code>_sel</code> so you use them with Underscore's excellent interfaces to the JavaScript collections.

<pre>
var Foo = _.datatype();
var Bar = _.datatype();

_.multi("cool", Foo, function(x) {
console.log("got type Foo!");
var Foo = _.Type({
initialize: function(z) {
this.z = z;
},
add: function(x, y) {
return [x, y].join("");
}
});

_.multi("cool", Bar, function(x) {
console.log("got type Bar!");
var Bar = _.Type({
initialize: function(z) {
this.z = z;
},
add: function(x, y) {
return x + y + thiz.z;
}
});

var a = new Foo();
var b = new Bar();

_.cool(a);
_.cool(b);
</pre>

With the above code the following also works great:
var a = new Foo("cool!");
var b = new Bar(6);

<pre>
_([a, b]).map(_.cool);
_([a, b]).map(_sel.add(4, 5));
</pre>

0 comments on commit 494ffbf

Please sign in to comment.