Hi, I''ve been trying out Prototype''s framework for Class
creation.
I''ve read the code and made an implementation of the ruby feature
method_missing. Are there any other attempts to achieve this. Is it
needed? Mine is probably quite buggy. =)
Put this code in a html-page that includes prototype to try out my
small example. It monkey patches Class.create and
Class.Methods.addMethods. The $super keyword doesn''t work, so it need
to be rewritten. It will only work for code that is executed within
the context of a class, so keep it pure OO!
var Class = {
create: function() {
var parent = null, properties = $A(arguments);
if (Object.isFunction(properties[0]))
parent = properties.shift();
function klass() {
this.initialize.apply(this, arguments);
}
document.writeln("<div
style=''background:#aaf''>Code for class");
Object.extend(klass, Class.Methods);
// *** Adding method missing support functions ***
Object.extend(klass.prototype, {
send: function(method) {
var args = $A(arguments); args.shift();
return this[method] ? this[method].apply(this, args) :
this.method_missing(method, args);
},
method_missing: function(method) {
throw("method missing " + method);
}
});
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
var subclass = function() { };
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
parent.subclasses.push(klass);
}
for (var i = 0; i < properties.length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;
klass.prototype.constructor = klass;
document.writeln("</div>");
return klass;
}
};
Class.Methods = {
addMethods: function(source) {
var ancestor = this.superclass && this.superclass.prototype;
for (var property in source) {
var value = source[property];
if (ancestor && Object.isFunction(value) &&
value.argumentNames().first() == "$super") {
var method = value, value = Object.extend((function(m) {
return function() { return ancestor[m].apply(this,
arguments) };
})(property).wrap(method), {
valueOf: function() { return method },
toString: function() { return method.toString() }
});
}
// *** Replacing method calls this.f(x,y) with
this.send(''f'',
x, y) ***
value = value.toString().replace(/this\.([a-z_1-9]+)\(/g,
function(ignore, method) { return
"this.send(''"+method
+"'',";});
document.writeln("<pre>" + value +
"</pre>");
this.prototype[property] = eval(value.toString());
}
return this;
}
};
// A small method_missing javascript example
var Person = Class.create({
initialize: function(name) {
this.name = name;
document.writeln(this.say("I see the light.")); // Method
exists.
document.writeln("<br/>");
document.writeln(this.says("I''m born!")); // Triggers
method_missing.
},
say: function(message) {
return this.name + '': '' + message;
},
method_missing: function() {
return "You missed with (" + $A(arguments).join(", ")
+ ")";
}
});
var john = new Person(''Long John'');
// Will print
// -> Long John: I see the light.
// -> You missed with (says, I''m born!)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Spinoffs" group.
To post to this group, send email to
rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---