The recent discussion about namespacing and native extensions in this
... had me asking myself, "how would I build a namespaced version of
the Prototype library?
Here's my stab at an answer. As has already been noted, the challenge
is really in preserving the utility of the native extensions, so I'm
gonna limit my discussion to that aspect of things for now.
One of the first things I concluded is that having "Prototype" as the
name of the root node sucks. Nobody wants to have to type that 100
times a day. Nor is asking developers to create a local alias, ala
"var P = Prototype" or something like that, feasible. Sure, we
shouldn't do anything to prevent that, but there are some things a
library should dictate, one of which is the name of the root node that
99% of people are going to use. Thus, I would start by defining a new
root node with a short, reasonably unique name that's easy to type.
For now, let's call it "qip". (humor me.)
What's interesting about this is that it implies a new library
("Qip"?) that is distinct from Prototype, which ain't a half-bad idea:
A spinoff library that can be used by Prototype to provide it's native
API extensions, but that might also be used standalone in other
libraries. This would be consistent with the emerging trend in
The design of the namespaced APIs is straight-forward: there are nodes
for qip.Array, qip.Object, qip.Function, etc., and methods hanging off
those. E.g. qip.String.endsWith() instead of String#endsWith(). I'll
assume implementation of this side of things is self-evident.
The biggest challenge lies in providing a way to optionally and
efficiently map the namespaced APIs onto native prototypes, if that's
what developers want. The problem is that the signatures have to
change because in a namespaced API there's always an explicit context
argument; an argument that has to go away and be replaced by 'this'
when assigned to a native prototype object. E.g. qip.String.endsWith
(aString, substring) has to become String#endsWith(substr).
While this method adaptation can be accomplished with
Function#methodize(), it's not practical due to the performance
problems that come from creating wrapped functions. These are core
extensions to native APIs - they need to have comparable performance,
which methodize() doesn't offer.
My proposed solution is pretty simple: it's fairly trivial to create a
modified clone of a namespaced function that can be assigned to a
prototype object. I've put together a code snippet illustrating the
Obviously this is just a rough outline of how to go about doing this,
but I think it addresses the basic requirements of ease-of-use,
configurability, and performance. I'd love to hear what people think,
especially if there are requirements that I haven't thought of.
You received this message because you are subscribed to the Google Groups
"Prototype: Core" group.
To post to this group, send email to email@example.com
To unsubscribe from this group, send email to
For more options, visit this group at