Skip to content

Instantly share code, notes, and snippets.

@yuki-takeichi
Forked from hirokidaichi/gist:11403157
Last active August 29, 2015 14:00
Show Gist options
  • Save yuki-takeichi/08307b3985838236e2fd to your computer and use it in GitHub Desktop.
Save yuki-takeichi/08307b3985838236e2fd to your computer and use it in GitHub Desktop.
var DISPATCH_TABLE = {};
DISPATCH_TABLE.Person = {
intro : function(_self){
return "I am just a Person,and my name is "+_self.name;
}
};
DISPATCH_TABLE.Student = {
intro : function(_self){
return "I am a Student,and my name is "+_self.name;
},
study : function(_self){
return "I'm studying...";
}
};
DISPATCH_TABLE.Superman = {
intro : function(_self) {
return "Hahaha! I'm a "+_self.name;
}
};
DISPATCH_TABLE.Flyable = {
fly : function(_self) {
return "Shoooooooooooooooon!";
}
};
DISPATCH_TABLE.Mant = {
/*
fly : function(_self) {
return "Fooo!";
}
*/
};
DISPATCH_TABLE.Accelerator = {
fly : function(_self) {
return "Bhoooouuuououoouououou!";
}
};
var CLASS_HIERARCY = {};
var MODULE_HIERARCY = {};
var PREPEND_MODULE_HIERARCY = {};
var me = {
_class_ : 'Person',
name : 'daichi hiroki',
age : 30,
study : "computer science"
};
var him = {
_class_ : 'Student',
name : 'hoge piyonosuke',
age : 20,
study : "complex system"
};
var superman = {
_class_ : 'Superman',
name : 'Tarou',
age : 777
};
function sendMessage(object,message,args){
function findMethod(className, message) {
var method;
// traverse prepend hierarchy
for (var i = 0; i < PREPEND_MODULE_HIERARCY[className].length; i ++) {
var moduleName = PREPEND_MODULE_HIERARCY[className][i];
method = findMethod(moduleName, message);
if (method !== undefined) { return method; }
}
// search current dispatch table
var klass = DISPATCH_TABLE[className];
if (klass === undefined) { return null; }
var method = klass[message];
if (method !== undefined) { return method; }
// traverse include hierarchy
for (var i = 0; i < MODULE_HIERARCY[className].length; i ++) {
var moduleName = MODULE_HIERARCY[className][i];
method = findMethod(moduleName, message);
if (method !== undefined) { return method; }
}
// resolve next inherit relation
return findMethod(CLASS_HIERARCY[className], message);
}
var method = findMethod(object._class_, message);
if (method === null) { return null; }
return method( object ,args );
}
//Work3-1
// class Child < Parent end
function extend(childName,parentName) {
CLASS_HIERARCY[childName] = parentName;
}
//Work3-2
// class Child
// include Module
// end
function include(targetClassName,moduleName){
var classList = MODULE_HIERARCY[targetClassName];
if (classList === undefined) {
MODULE_HIERARCY[targetClassName] = [moduleName];
return ;
}
classList.unshift(moduleName);
}
//Work3-3
// class Child
// prepend Module
// end
function prepend(targetClassName,moduleName){
var classList = PREPEND_MODULE_HIERARCY[targetClassName];
if (classList === undefined) {
PREPEND_MODULE_HIERARCY[targetClassName] = [moduleName];
return ;
}
classList.unshift(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')
*/
// work 3-1
console.log(sendMessage(me,'intro'));
extend('Student', 'Person');
console.log(sendMessage(him,'intro'));
console.log(sendMessage(him,'study'));
// work 3-2
include('Superman', 'Flyable');
include('Mant', 'Accelerator');
include('Superman', 'Mant');
console.log(sendMessage(superman, 'intro'));
console.log(sendMessage(superman, 'fly'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment