Andrew Tetlaw wrote:
OK trying to say this as tactfully as possible, because it's not

I welcome feedback. Javascript can be a difficult language to develop in so I am always looking for ways to improve things.

[...snip info about prototype's use of globals...]
This can only create a huge mess as everyone tries to muck around
treading on each others global namespace claims.

Yes namespace really can be a problem in Javascript. I have encountered the problem first-hand.

I propose that all contributors of Prototype based user scripts create
their on namespaced objects and leave the global namespace to
Prototype. I'd go a little further and suggest for sanity's sake we
also leave any namespace created by Prototype well alone too.

The problem seems to me an issue of convenience vs compatibility. Java uses the organization name (us.afaik.blah.blah.blah) to organize the namespace. So if we went that route I could define an object called:

us.afaik.effects.Element.Rotate

This would ensure separation of namespaces but isn't very convenience to work with. Also, Javascript is unique in that everything must be downloaded to the client. This means we want to avoid unnecessary code if possible.

To me if you look even deeper there is also another harm in creating ridged namespaces as in Java. I find there to be a synergy in being able to share namespaces from separate projects. I see the issue as needing balance. Sharing namespace across projects encourages good OO code in some cases. Othertimes it just causes problems. Instead of doing:

(new us.afaik.util.String('<img src="foo.gif" />')).preloadImgs()

or handing it in a procedural manor:

us.afaik.util.String.preloadImgs('<img src="foo.gif" />');

I can just write clean OO code that does:

'<img src="foo.gif" />'.preloadImgs();

I see this as a good use of adding to the built-in objects. It allows any code that is working with my library to easily preload any images defined in a string. They don't have to interact with a special string object (the Java way) and they don't have to use procedural code. They just call an method on an object.

But like everything it must be done in moderation. To me the test is are you doing something that another developer would expect? Take for example:

String.prototype.replace = function() { return ''; }

This is bad! Although for some odd reason it may be what you need it will not be what other applications expect. On the other hand:

String.prototype.trim = function() {
        return this.replace(/^\s+/, '').replace(/\s+$/, '')
}

This is good! Because it allows a programmer to call a trim() method on any string object (no matter how that object was created) which does what a programmer expects. Even if another library defines a trim method it may be different in implementation but the basic concept will be the same.

In both cases we defined a method on a built-in object. The differences is in how we used that power. The first case we did something that a developer would not expect, while the second did something a developer would expect. The same thing applies to building on existing objects in Prototype (or any other library). Assume that we build our extensions in a way that is obvious we will avoid problems while still getting great synergy.

The other consideration to make is the scope of the project. A project like Prototype or Script.aculo.us has to be more careful because it is complex and used in a wide variety of environments. On the other hand my stupid object is a simple 123 lines of code. If you do encounter a conflict it is small enough to maintain a simple patch that avoids the conflict. I also welcome any changes that might need to be made to avoid conflicts with an existing library.

This image rotation script, while useful, I would not be confident in
using because it, adds to the Prototype Element object, it adds to the
Prototype object, it adds an image cache to the String object (???).

I said previously that adding to core objects and objects in other libraries is a balance. Did I make the right choices? Probably not completely but I can fix anything that pops up.

In general I feel that the code I added to existing objects is in the spirit of those objects (Prototype.ImageTag matches Prototype.ScriptTag, String.extractImgs matches String.extractScripts, etc.). Even the "Rotate" property added to the Element object to store my object is reasonable (what else would rotate mean?). But I don't begrudge anybody for thinking it is too liberal. Just a design choice.

Just my two cents. I welcome comments from others.

Eric

_______________________________________________
Rails-spinoffs mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs

Reply via email to