Prototype and the global namespace

31 katselukertaa
Siirry ensimmäiseen lukemattomaan viestiin

Diodeus

lukematon,
3.3.2009 klo 11.35.243.3.2009
vastaanottaja Prototype: Core
Dion Almaer's (of Ajaxian fame) new project Bespin (http://
labs.mozilla.com/projects/bespin/) is a full-blown online code editing
system based on Prototype. There has been a recent move to Dojo, the
main reason being Prototype's pollution of the global namespace
(http://almaer.com/blog/bespin-now-learning-some-art-in-the-dojo).

Is there any plan to remedy this situation?

kangax

lukematon,
3.3.2009 klo 12.43.133.3.2009
vastaanottaja Prototype: Core
It's not clear what will be left of Prototype if it was to change its
core way of doing things - extending objects, both native and host
ones. While host objects extensions can be changed in favor of
wrappers (without much breakage), preventing native object extensions
would practically eliminate most of Prototype's charm (charm that is
very attractive in some environments, yet poisonous in others - as you
can see with Bespin not being able to provide ease of extensibility
and collaboration).

--
kangax

Mislav Marohnić

lukematon,
3.3.2009 klo 12.44.483.3.2009
vastaanottaja prototy...@googlegroups.com
On Tue, Mar 3, 2009 at 17:35, Diodeus <dio...@gmail.com> wrote:

Is there any plan to remedy this situation?

If you look at the development on master since 1.6.0.3, you can see that some significant effort has been put into re-organizing Prototype modules and better usage of the module pattern in JavaScript.

However, main modules like Hash, Template, Enumerable, etc. are going to stay in the global namespace until some major release where the core team decides to pull them under the Prototype namespace. It is not certain when will that happen, but a year ago (or more) I showed how it's fairly easy to namespace Prototype yourself with few minor changes to the library. Any project like Bespin can use this approach if it wants to bundle Prototype and nobody has to wait for the prototype core team to do it.

However, the core team definitely decided (or so they sounded) to stop extending DOM elements in the future major release. It is just too slow in IE and has bitten back on several occasions in other browsers that implemented some of the methods natively (if I recall correctly).

It is not clear will Prototype ever stop extending native prototypes like Function, Array, Number, Event, etc. I vote no, because if Prototype ever stops extending DOM nodes, extending native prototypes, and touching the rest of the runtime environment all-together, it will cease to be the "Prototype" library.

Mislav Marohnić

lukematon,
3.3.2009 klo 12.53.363.3.2009
vastaanottaja prototy...@googlegroups.com
On Tue, Mar 3, 2009 at 18:43, kangax <kan...@gmail.com> wrote:

It's not clear what will be left of Prototype if it was to change its
core way of doing things -

Exactly.

What's the big deal? Can anybody explain a concrete situation where you put two libraries together and the browser goes up in flames? Has anybody really got bitten by modules in the global namespace like Template or Hash?

Prototype was for some time the world's most popular library exactly for the reason it provided these classes/methods/features.

kangax

lukematon,
3.3.2009 klo 13.13.553.3.2009
vastaanottaja Prototype: Core
Some time ago, there were no hundreds of jQuery, mootools or whatever
else extensions floating around, and I don't think compatibility was
as crucial as it is now. Yes, I remember Prototype conflicting with
some MS' map-related libraries, with Ext.js and its
Function.prototype.* extensions, with jQuery's `$`, with a bunch of
Mootools "globals", and some of the minor libraries which rely on
native array extensions like `map` : )

--
kangax

Mislav Marohnić

lukematon,
3.3.2009 klo 13.39.573.3.2009
vastaanottaja prototy...@googlegroups.com
On Tue, Mar 3, 2009 at 19:13, kangax <kan...@gmail.com> wrote:

... and some of the minor libraries which rely on

native array extensions like `map` : )

Well, I'm definitely all for avoiding overwriting native JavaScript 1.6+ Array stuff.
I know we lose $break functionality, but this is a price we have to pay for vioaliting our core principle of never shadowing native methods.

Tobie Langel

lukematon,
3.3.2009 klo 14.02.353.3.2009
vastaanottaja Prototype: Core
> Well, I'm definitely all for avoiding overwriting native JavaScript 1.6+
> Array stuff.
> I know we lose $break functionality, but this is a price we have to pay for
> vioaliting our core principle of never shadowing native methods.

+1

Nick Stakenburg

lukematon,
9.3.2009 klo 21.52.559.3.2009
vastaanottaja Prototype: Core
> What's the big deal? Can anybody explain a concrete situation where you put two libraries together and the browser goes up in flames? Has anybody really got bitten by modules in the global namespace like Template or Hash?

Mootools shares many of Prototype's globals. There's not much fun in
porting Mootools code to Prototype or the other way around.

> Prototype was for some time the world's most popular library exactly for the reason it provided these classes/methods/features.

Untill people stopped caring about using multiple frameworks on the
same page. Throwing stuff together on a page praying for it to work is
the way the majority "codes" right now.

I think switching to a Prototype namespace is the way forward if you
want to keep having competition with other frameworks, turning the
charm into an optional thing for people who can afford it. I don't see
a project like Bespin wrapping up a Prototype namespace themselves,
too much trouble when updating, it should be something Prototype (2?)
provides out of the box.

Mislav Marohnić

lukematon,
10.3.2009 klo 6.00.5110.3.2009
vastaanottaja prototy...@googlegroups.com
On Tue, Mar 10, 2009 at 02:52, Nick Stakenburg <nicksta...@gmail.com> wrote:

> What's the big deal? Can anybody explain a concrete situation where you put two libraries together and the browser goes up in flames? Has anybody really got bitten by modules in the global namespace like Template or Hash?

Mootools shares many of Prototype's globals. There's not much fun in
porting Mootools code to Prototype or the other way around.

I get this, and I agree on namespacing globals - it isn't going to affect our workflow, we'll just copy stuff from Prototype to global namespace for legacy scripts. (There will probably be a compat.js script that does that when the release is ready.) 

What I want is the community's opinion on augmenting native prototypes: Number, Function, Event etc. Is it good/bad? Is this what makes you happy while writing code? Here's the thing:
  1. Prototype and "LibraryA" can easily co-exist if LibraryA doesn't augment native prototypes;
  2. Prototype and "LibraryB" cannot co-exist if LibraryB augments native prototypes, too - high chances for name collisions.
So augmenting native prototypes is OK if you're the only library that does it. If there are others, the situation produces sad pandas.

Same problem with augmenting Object.prototype: we know that it hurts looping over properties, but suppose script writers got around looping problems -- what if everyone augmented Object.prototype? It would be a massive crash 'n' burn.

Object.prototype is verboten. Should we say that augmenting native prototypes is verboten, too?

If so, how should be re-brand the Prototype library? :)
j/k

Thanks,
# Mislav

Alexandre Morgaut

lukematon,
10.3.2009 klo 9.22.3010.3.2009
vastaanottaja prototy...@googlegroups.com

A good way would be to manage a config option that can desactivate Prototype's overload
By default Prototype should work as it does actually so it is still compatible for thoose which already use Prototype and doesn't want to manage a configuration for it


Date: Tue, 10 Mar 2009 11:00:51 +0100
Subject: [Prototype-core] Re: Prototype and the global namespace
From: mislav....@gmail.com
To: prototy...@googlegroups.com

Discutez sur Messenger où que vous soyez ! Mettez Messenger sur votre mobile !

Rob Tsuk

lukematon,
10.3.2009 klo 10.27.3810.3.2009
vastaanottaja prototy...@googlegroups.com
Let me introduce myself before responding in particular. I work at Palm on the Mojo application framework, which includes Prototype as part of its interface and implementation.

I'll post a second message explaining how it is we came to include Prototype, but I don't want to hijack this thread for that.

On Tue, Mar 10, 2009 at 3:00 AM, Mislav Marohnić <mislav....@gmail.com> wrote:
What I want is the community's opinion on augmenting native prototypes: Number, Function, Event etc. Is it good/bad? Is this what makes you happy while writing code? 

The opinion of the people working on Mojo at Palm as well as our internal application developers is that extending native prototypes indeed makes us happy.

One example is the bind() method on Function. Mojo requires application developers to create a certain number of objects whose methods are likely to be used as callbacks, and bind() is invaluable for establishing the "this' keyword in those cases. It would not improve matters at all to have to call Prototype.Function.bind(this.handleRequest, this) rather than this.handleRequest.bind(this).

Even if there were an option to run Prototype in a namespace and have it not extend native prototypes, I doubt we would enable it for Mojo. If we did, we'd have to make all the code in the framework avoid depending on the prototypes and use the namespaces, and I don't the what that would do to code clarity in the framework would be worth the theoretical compatibility.

kangax

lukematon,
10.3.2009 klo 14.48.1010.3.2009
vastaanottaja Prototype: Core
On Mar 10, 10:27 am, Rob Tsuk <robt...@gmail.com> wrote:
[...]
> One example is the bind() method on Function. Mojo requires application
> developers to create a certain number of objects whose methods are likely to
> be used as callbacks, and bind() is invaluable for establishing the "this'
> keyword in those cases. It would not improve matters at all to have to call
> Prototype.Function.bind(this.handleRequest, this) rather than
> this.handleRequest.bind(this).

You don't have to call it like that : )
Properties can be aliased to local variables in closures. Local
variables are cheap and closures are flexible.

Does this really look/feel so bad?

var Widget = Class.create((function(){

var bind = Prototype.lang.bind;

return {
initialize: function(id) {
this.element = $(id);
this.init();
},
init: function()
this.element.observe('click', bind(this.onClick, this));
},
onClick: function(){
// ...
}
}
})());

I understand the ubiquity of `bind` and desire to access it directly
on a function (which is why ES3.1 introduces native `bind`), but if we
are talking about general use on the web (i.e. maximum compatibility),
I don't see how the alternative approach makes code any less clear or
any less pleasant to use. The only downside I see is that you have
another variable (local to your "class") to watch out for.

>
> Even if there were an option to run Prototype in a namespace and have it not
> extend native prototypes, I doubt we would enable it for Mojo. If we did,

That's the beauty of developing for a controlled environment (please
correct me if I'm wrong)

> we'd have to make all the code in the framework avoid depending on the
> prototypes and use the namespaces, and I don't the what that would do to
> code clarity in the framework would be worth the theoretical compatibility.

I think it's a myth that code clarity is being lost when moving from
oo approach to a more functional one. You only need to change the way
you approach things. It's good to remember that not relying on
augmenting *native prototypes* still allows to take advantage of
expressive prototypal nature of Javascript.

--
kangax

Rob Tsuk

lukematon,
10.3.2009 klo 15.14.0810.3.2009
vastaanottaja prototy...@googlegroups.com
I hadn't considered that particular functional approach. When we started on Mojo, we decided on using an OO style versus a functional one, as we guessed that it would be more familiar to the bulk of our potential developers. Certainly it was more familiar to everyone on the team.

Your example does look fine, although I don't like that I'd have to do that local variable trick in every class declaration.

My comparison of clarity had nothing to do with functional vs. OO. It was only a comparison of namespaced vs. prototypical access.

We do have the benefit of working in a controlled environment, although we'd like to allow other JavaScript libraries be able to co-exist with Mojo as much as possible. Once our SDK is out it will be interesting to see what's needed to make that happen.

Ryan Gahl

lukematon,
10.3.2009 klo 16.25.0710.3.2009
vastaanottaja prototy...@googlegroups.com
This pattern, which is a spin from the module pattern, allows many nice things, including the use of truly private, class level, (static, protected, etc) members. If you want to REALLY maximize performance and minimize the overhead of the grossly overused .bind() function, you can identify instance methods that really could be "private static" methods and move them into the class module's "global" area, passing in the instance reference instead of binding (thus, moving more towards functional looking code, but I still tend to think of it as OO, where these become private static members of the class).

To mashup kangax's pattern here with what I'm saying, and aim to just not use bind if you don't have to (which is a Good Thing)... consider the following slightly altered take(s) on kangax's code...

var Widget = Class.create((function() {
  //protected, static methods
  function init(widget) {
    widget.element.observe('click', onClick);
   
    //note, instead of using "bind" (which creates a copy of a function anyway), we simply create the method in our desired scope (imagine that!)
    function onClick() {
      // ... now "widget" is the instance reference to use in here

    }
  }
 
  return {
   initialize: function(id) {
     this.element = $(id);
     init(this);
   }
 }
})());


...and yet another variation is to use the constructor as the place to, you know... construct. I left the init() method at the static level for illustration.

var Widget = Class.create((function() {
  //protected, static methods
  function init(config) {
    config.widget.element.observe('click', config.onClickHandler);
  }
 
  return {
   initialize: function(id) {
     //early bind during construction:
     var me = this;
    
     //public properties...
     this.element = $(id);
    
     //private instance level methods... (replacement technique for using .bind())
     function onClick() {
       // ... now "me" is the instance reference to use in here
     }
    
     //use the static init method, passing in our instance level onClick handler (and of course the instance itself)...
     init({
        widget: this,
        onClickHandler: onClick
     });
   }
 }
})());


You'll notice that this pattern accomplishes several things. For starters, it hides methods that really shouldn't be exposed as a public interface on the instances anyway. The "say that it's private in the comments or by adding an underscore in front of it" technique is just lazy and Bad Form. It also avoids the overhead of using .bind() - which as you've discovered adds up quickly. The true purpose of .bind() is just to create a copy of a function, applied to the object you pass in. It is VERY convenient, and easy to use (and mis-use). However, just creating the copy of your method in the scope in which it is needed is all you have to do (no need for the cleverness). Then, no $A() overhead, and debugging is straight forward, AND you can truly hide members from calling code as appropriate... so while you're seeming to move towards more functional code you're also actually reaping _more_ of the benefits of OO.

It's a shift in thinking, but one that you'll grow to love if you make the investment.


Ryan Gahl
CEO
Nth Penguin, LLC
http://www.nthpenguin.com
--
Inquire: 1-920-574-2218
Blog: http://www.someElement.com
LinkedIn Profile: http://www.linkedin.com/in/ryangahl

Mislav Marohnić

lukematon,
10.3.2009 klo 16.25.3810.3.2009
vastaanottaja prototy...@googlegroups.com
On Tue, Mar 10, 2009 at 20:14, Rob Tsuk <rob...@gmail.com> wrote:

Your example does look fine, although I don't like that I'd have to do that local variable trick in every class declaration.

You could always have it in a module that wraps the complete code of your project. That way you have to only declare the shortcut once, but it still isn't part of the global namespace.

Tobie Langel

lukematon,
10.3.2009 klo 18.06.4310.3.2009
vastaanottaja Prototype: Core
A couple of thoughts about Function#bind:

- it's part of the ES 3.1 draft, so will be found in browsers natively
pretty soon, and
- it's been been completely rewritten for our next release, so the
overhead should be much lighter.

Regarding extensions of native prototypes in general, a lot of methods
originally introduced by Prototype (the so-called rubyisms), which
were then added to FF will make it to the ES 3.1 spec. Yes, there's
one infortunate issue with Array#reduce, but the fact there we're now
a lot more present on the ES 3.1 mailing list helps to make sure this
won't happen again.

One of the great assets of Prototype is it's language enhancement
features. One of the great issues of Prototype is the way this causes
pollution.

Ideally, we can achieve better balance between those for Prototype
2.0.

It's certainly on my plate!

Best,

Tobie






Radoslav Stankov

lukematon,
11.3.2009 klo 6.08.0511.3.2009
vastaanottaja Prototype: Core
I played with prototype to make it, less conflictable. I just wrap the
whole Prototype lib in closures, and just in the end exposed to the
global scope only the parts who I needed. It was good enough for me :)
but one of the main reasons I use prototype is the language extensions
( + Dom ones) and the power they give me.

Dion

lukematon,
24.3.2009 klo 1.53.0724.3.2009
vastaanottaja Prototype: Core
Hi chaps,

Just saw this post.

I wanted to be clear about something. Ben and I really like Prototype.
There is a reason that we choose it at first, and that is because we
like it so much. It feels right to us (I am a Ruby guy...). It extends
JavaScript in the way that we wish JS just *was*.

So, it was really hard to make the call on the switch. If
Thunderhead / Bespin component wasn't going to be something that lives
in any Web app, we wouldn't have had to make a switch at all, but
people were running into issues so we felt backed into a corner on it
(and there were other reasons too).

Having Prototype not make the extensions could have changed things for
us in this case, but I also agree that part of the reason we love
Prototype is because of "foo".trim() instead of dojo.trim("foo"). You
start to really hate seeing the same word again and again for no
reason! :)

I wish that there was an easy way to on the fly turn on and off the
ability and have it all scoped so no one could tread on each others
toes. Grrrrr.

Thanks for a great framework. We will be using it again real soon.

Cheers,

Dion

mag...@gmail.com

lukematon,
26.3.2009 klo 16.04.3726.3.2009
vastaanottaja Prototype: Core
Hello,

I work for a SaaS provider of community support forums for mid-large
companies. The latest version of our product is built using Proto and
Scripty, and I am a big fan of the two libraries (I chose to go with
them). I am now faced with a dilemma where our white label product
needs to seamlessly integrate with a customers branding, which more
often contains JavaScript libraries from their main site. We have
been able to get around conflicts if they use jQuery (via noConflict)
and other well namespaced libraries (Dojo, Ext, etc). However the
need for our core product to be able to play nice with whatever
JavaScript customers might add has grown from a small murmur to a loud
roar. I have made a couple failed attempts at putting Proto in a
closure providing "exposing" and "noConflict" methods, using an iFrame
to have a clean scope and most recently I am trying to use ProtoSafe.
I have gotten ProtoSafe to work, however I am not thrilled about
having to "modify" source code prior to it being served and then
eval'ing it on the client side.

All of this work has led to the discussion of switching off of
Prototype, and given that there does not appear to be consensus
amongst the core developers to provide namespacing in the very near
future I fear that our days of using Prototype are numbered.

Regards,
Adam Ayres

Joran

lukematon,
29.3.2009 klo 6.51.1529.3.2009
vastaanottaja Prototype: Core
Native prototype extensions + elegant semantics = Prototype.
Vastaa kaikille
Vastaa kirjoittajalle
Välitä
0 uutta viestiä