Created
April 30, 2014 09:04
-
-
Save hirokidaichi/308c1a701c76e845723c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var DISPATCH_TABLE = {}; | |
DISPATCH_TABLE.Person = { | |
intro: function(_self) { | |
return "I am just a Person,and my name is " + _self.name; | |
} | |
}; | |
TYPE_TABLE = {}; | |
ANCESTOR_TABLE = {}; | |
Array.prototype.first = function(predicate) { | |
for (var i = 0, l = this.length; i < l; i++) { | |
if (predicate(this[i])) | |
return this[i]; | |
} | |
} | |
Array.prototype.flatten = function() { | |
return Array.prototype.concat.apply([], this); | |
} | |
function sendMessage(object, message, args) { | |
var tables = [object._singleton_, ancestors(object._class_).map(function(classOrModule) { | |
return DISPATCH_TABLE[classOrModule] | |
})].flatten(); | |
var resolved = tables.first(function(table) { | |
return !!table[message]; | |
}); | |
var method = resolved[message]; | |
return method(object, args); | |
} | |
function defClass(className, dispatchTable) { | |
DISPATCH_TABLE[className] = dispatchTable; | |
return _classAncestor(className) | |
} | |
function defModule(moduleName, dispatchTable) { | |
DISPATCH_TABLE[moduleName] = dispatchTable; | |
} | |
function extend(className, parentName) { | |
var ancestor = _classAncestor(className); | |
if (ancestor) throw ("multi inheritance"); | |
return _classAncestor(className, parentName); | |
} | |
function include(className, moduleName) { | |
var ancestor = _includeAncestor(className); | |
ancestor.unshift(moduleName); | |
return ancestor; | |
} | |
function prepend(className, moduleName) { | |
var ancestor = _prependAncestor(className); | |
ancestor.unshift(moduleName); | |
return ancestor; | |
} | |
function singleton(object, dispatchTable) { | |
object._singleton_ = dispatchTable; | |
} | |
function _nullThenSet(obj, key, defaultValue) { | |
if (!obj[key]) { | |
obj[key] = defaultValue | |
} | |
return obj[key]; | |
} | |
function _classAncestor(className, setter) { | |
var ancestor = _nullThenSet(ANCESTOR_TABLE, className, {}); | |
if (setter) { | |
ancestor.parent = setter; | |
} | |
return ancestor.parent; | |
} | |
function _includeAncestor(className, setter) { | |
var ancestor = _nullThenSet(ANCESTOR_TABLE, className, {}); | |
if (setter) { | |
ancestor.include = setter; | |
} | |
return _nullThenSet(ancestor, "module", []); | |
} | |
function _prependAncestor(className, setter) { | |
var ancestor = _nullThenSet(ANCESTOR_TABLE, className, {}); | |
if (setter) { | |
ancestor.prepend = setter; | |
} | |
return _nullThenSet(ancestor, "prepend", []); | |
} | |
function ancestors(className) { | |
return [ | |
_prependAncestor(className).map(ancestors).flatten(), | |
className, | |
_includeAncestor(className).map(ancestors).flatten(), | |
_classAncestor(className)].flatten().filter(function(e) { | |
return !!e | |
}); | |
} | |
defClass("Parent", {}); | |
defClass("Clazz", {}); | |
defModule("A", {}); | |
defModule("B", {}); | |
defModule("C", {}); | |
defModule("D",{}); | |
extend("Clazz", "Parent"); | |
include("Clazz", "A"); | |
include("Clazz", "B"); | |
include("A","D"); | |
prepend("Clazz", "C"); | |
console.log(ancestors('Clazz')); | |
/* | |
Work3-1 | |
// class Child < Parent end | |
function extend(childName,parentName) { | |
} | |
Work3-2 | |
// class Child | |
// include Module | |
// end | |
function include(targetClassName,moduleName){ | |
} | |
Work3-3 | |
// class Child | |
// prepend Module | |
// end | |
function prepend(targetClassName,moduleName){ | |
} | |
Work3-4 | |
// class << object | |
// | |
// end | |
function singleton(object,dispatchTable){ | |
} | |
Work3-5 | |
implement method_missing | |
sendMessage(me,'no_such_a_method') => NoSuchAMethod | |
Work3-6 | |
implement double dispatch | |
DISPATCH_TABLE['ClassA']['ClassB'].collide = function(){} | |
sendMessage([me,you],'collide') | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment