March 6th, 2006

Prototype Gets Some Serious Syntactic Sugar

20 comments on 390 words

I’ve hoped for a while that Prototype would implement something similar to what JQuery has going on for DOM elements. The current Element object in Prototype is packed full of great stuff, but how you access those methods isn’t exactly ideal.

Here is an example of something you might have done using Prototype:


   this.element = $('element');
   Element.hide(this.element);

Now we can do this:


 this.element = $('element');
 this.element.hide();

All of the methods of Element are now accessible this way. We can even access Script.aculo.us effects this way too.


 $('element').visualEffect('highlight');

Now thats just sweet stuff. Want to add your own methods to Element? No problem!


   Custom = {
     contrast: function(element) {
       var actor = $(element);
       actor.setStyle({color: '#000', backgroundColor: 'yellow'});
       return actor;
     }
   }

   Object.extend(Element.Methods, Custom);

Now we can call the contrast method above in the same fasion:


  $('element').contrast();

It’s not all good though, there are some things you can’t do such as chain methods of Element together or any other method that doesn’t return a node. The code below will not work.


$('element').setStyle({color: '#ccc'}).show();

However, this will work:


//Works
$('element').contrast().show();

//Doesn't work
$('element').show().contrast();

I expect we’ll see Element evolve in the future and allow us the ability to chain methods.

Thats a quick rundown of the new features. Until next time–Happy Prototyping!

Discussion

  1. rick rick said on March 6th

    Simply add ‘return element;’ to get method chaining to work in contrast()

  2. Jason Jason said on March 7th

    What version of prototype does this apply to…the early versions of 1.5 still in development?

  3. Justin Palmer Justin Palmer said on March 7th

    Jason: This is the Edge Rails version. You can find it here.

  4. cody lindley cody lindley said on March 7th

    Now were talking…think we might see this in version 1.5 (standalone js file)?

  5. Andrew Dupont Andrew Dupont said on March 7th

    It seems to me that method chaining might be in the pipeline, since any method that doesn’t return a value may as well be written to return itself. In the meantime, you can go into the source and edit these methods to return their element arguments.

  6. Sebastian Sebastian said on March 7th

    Take a look at jQuery, it has “ChainableMethods” as a core feature.

    Does anybody know a good comparison between prototype and jQuery?

  7. Konstantin Konstantin said on March 8th

    Sebastian: You can use jQuery and Prototype together.

  8. Sebastian Sebastian said on March 8th

    Konstantin: Thanks for your answer. And yes, i know. But I’m a little bit confused since there was some Prototype bashing:

    Extending Array would break JavaScript and Prototype would not play nice with other JavaScript Libraries.

    So i wonder if that’s still the case, that’s why i asked for a comparison.

    Sebastian

  9. Ryan Gahl Ryan Gahl said on March 10th

    So the deal here is, you all don’t like writing separate lines of code (readable), so you want to make every method call return the object which called it so you can use (costly) object chains (not as readable)?

    okkk….

  10. Martin Martin said on March 10th

    Syntactic sugar. Working on this must be why Sam is not incorporating the bug fixes that linger around in the rail’s Trac for ages.

    No, I am not bitter or anything.

  11. manuel manuel said on March 10th

    Agree with Martin. What about some “syntactic sugar” to avoid JS syntax errors in IE5.0?

  12. Piotr Usewicz Piotr Usewicz said on March 10th

    Ah, simply gorgeous.

  13. Justin Palmer Justin Palmer said on March 10th

    Martin, manuel: Sam has actually been working on this for sometime now, even before JQuery popped on the scene.

    I do sympathize with you guys though. Sam isn’t the most vocal of characters so it’s hard to know where he’s taking Prototype and the status of patches/progress. I know that his intentions are good and his standards are high, so I think we’ll see fixes coming soon.

  14. Hermann Klinke Hermann Klinke said on March 10th

    Oh, you mean you made it object oriented ;-).

  15. Andrew Dupont Andrew Dupont said on March 10th
    So the deal here is, you all don’t like writing separate lines of code (readable), so you want to make every method call return the object which called it so you can use (costly) object chains (not as readable)?

    Yes, it’s obviously that simple. We’re horrible programmers!

    Chaining methods is sometimes called for. When used correctly, it makes the code more readable. When used improperly and to an extreme, it makes the code less readable, but I’d prefer to make that decision on my own, rather than have it mandated for me.

    The barrier of entry to using Prototype is quite high, given how little documentation exists. I imagine those who use it already know how to write JavaScript and can be trusted to use it wisely.

  16. Ryan Gahl Ryan Gahl said on March 10th

    Chaining methods is never necessary, and always add stack stress. Not saying you have to worry about the stack all the time, but it’s a good practice. Anyway, take what I say with a grain of salt, I’m pretty cynical and I comment irresponsibly.

  17. dak dak said on March 10th

    What’s stack stress? Especially since activation records in JavaScript are almost assuredly on the heap, and there I’d guess that an activation record in JavaScript consists of a pointer to the return value, so that returning a value is performed via a pointer assignment; no allocation, pushing, or popping necessary.

    In other words, I’d very seriously doubt that there’s any practical difference between a.b().c().d() and the equivalent written out across several lines. But I’m quite certain that, even in time-sensitive code paths, this is just about the last thing you’ll need to optimize.

    As for necessity: all that’s necessary is a Turing machine, it’s just not very pleasant. Arguing from the point of necessity is… well, unnecessary.

  18. Caine Caine said on March 14th

    Well I will say that chaining methods makes for a debugging nightmare. If something blows up, you have no idea where it happened. Which of the chained functions blew up on that line?

  19. Anita Anita said on April 4th

    I’d very seriously doubt that there’s any practical difference between a.b().c(). d() and the equivalent written out across several lines. Agree.

  20. I am surprised - interesting comments http://spankzilla.atspace.com said on April 28th

    Lovely, I must say, there is not so much themes, which deserve a comment. This one is realy needful http://spankzilla.atspace.com

Sorry, comments are closed for this article.