<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Debuggable.com - Blog</title><link>http://www.debuggable.com/</link><description /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/debuggable" /><feedburner:info uri="debuggable" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>JavaScript Meetup Hamburg + Slides</title><link>http://feedproxy.google.com/~r/debuggable/~3/nkohVEbm3a0/javascript-meetup-hamburg-slides:4b8f9986-4e64-4755-b420-074dcbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/javascript-meetup-hamburg-slides:4b8f9986-4e64-4755-b420-074dcbdd56cb</guid><description>&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Andy Wenk posted &lt;a href="http://blog.netzmeister-st-pauli.com/post/426345602/hhjs-first-meetup-hamburg"&gt;a very nice summary&lt;/a&gt; of the event.&lt;/p&gt;

&lt;p&gt;Last night Tim and I took a little road trip to Hamburg. I had no idea the &lt;a href="http://en.wikipedia.org/wiki/Reeperbahn"&gt;Reeperbahn&lt;/a&gt; looked like Las Vegas : ).&lt;/p&gt;

&lt;p&gt;Anyway, our actual destination was the first &lt;a href="http://twitter.com/hhjs"&gt;Hamburg JS&lt;/a&gt; meetup where &lt;a href="http://www.nonblocking.io/"&gt;Malte Ubl&lt;/a&gt; invited me to speak about node.js. The turnout was fantastic, and thanks to &lt;a href="http://www.sinnerschrader.de/"&gt;SinnerSchrader&lt;/a&gt;'s hosting of the event, there was plenty of pizza, beer and an absolutely fantastic location.&lt;/p&gt;

&lt;p&gt;I've also updated my previous node.js talk, all the examples should now be 0.1.30+ compatible, and the section about "The Future" of node has a more recent and interesting list of things that are on the radar:&lt;/p&gt;

&lt;div style="width:425px" id="__ss_3332942"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/the_undefined/nodejs-a-quick-tour-ii" title="Node.js - A Quick Tour II"&gt;Node.js - A Quick Tour II&lt;/a&gt;&lt;/strong&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=node-100304052653-phpapp02&amp;stripped_title=nodejs-a-quick-tour-ii" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=node-100304052653-phpapp02&amp;stripped_title=nodejs-a-quick-tour-ii" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;

&lt;p&gt;You can also &lt;a href="http://felixge.s3.amazonaws.com/10/nodejs-a-quick-tour-2.pdf"&gt;download the slides as PDF&lt;/a&gt; (164 kb).&lt;/p&gt;

&lt;p&gt;--fg&lt;/p&gt;

&lt;p&gt;&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b8f9986-4e64-4755-b420-074dcbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/nkohVEbm3a0" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Thu, 04 Mar 2010 11:43:53 +0000</pubDate><comments>http://www.debuggable.com/posts/javascript-meetup-hamburg-slides:4b8f9986-4e64-4755-b420-074dcbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/javascript-meetup-hamburg-slides:4b8f9986-4e64-4755-b420-074dcbdd56cb</feedburner:origLink></item><item><title>Apology to the CSF and CakeDC</title><link>http://feedproxy.google.com/~r/debuggable/~3/e_ZPWdQ1uFw/apology-to-the-csf-and-cakedc:4b743f89-ef24-4d73-9443-01a2cbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/apology-to-the-csf-and-cakedc:4b743f89-ef24-4d73-9443-01a2cbdd56cb</guid><description>&lt;p&gt;After our &lt;a href="http://debuggable.com/posts/the-high-cost-of-open-source:4b58e599-a9a0-4774-b3ff-302bcbdd56cb"&gt;previous post&lt;/a&gt;, we are very happy to announce our formal apology to the &lt;a href="http://cakedc.com/"&gt;CakeDC&lt;/a&gt; and the &lt;a href="http://cakefoundation.org/"&gt;Cake Software Foundation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After further discussions with the CSF we have come to understand why the CSF needs to have an agreement with the venue, this is required to free the funds for making this transaction since the CSF would be legally responsible for the payment. Larry E. Masters has helped us to work out all misunderstandings in that regard, and we would also like to formally apologize to him.&lt;/p&gt;

&lt;p&gt;Beyond that, we are also apologizing to the CakePHP community, for jumping the gun early, and having caused damage to the image of the project. This was not our intention, and we only did that, as a last resort to see the venue paid and defending our business from harm.&lt;/p&gt;

&lt;p&gt;As previously announced, we are still planning on being valuable members to the community, releasing plugins &amp;amp; components as open source.&lt;/p&gt;

&lt;p&gt;We are grateful to all those who donated, and will reimburse everybody completely once the venue has been paid in full, or in no longer than 60 days from the time of your donation, whichever comes first. We will take down the pledgie site also. Until then we will continue to pay the venue 500 EUR / month, so that any eventual delays will not be to their disadvantage. We also had a misunderstanding with the agreement Larry E. Masters had made to personally cover the 500 EUR / month while the CSF was trying to clear up the situation with the 501(c)(3) status. He also clarified, that the CSF is an independent entity from the CakeDC with its own board of directors which currently hold these positions temporarily and that a new board will be in place when all of this legal stuff is completed.&lt;/p&gt;

&lt;p&gt;Please, do not let any of this reflect on your opinion about the framework. Every community has their difficult moments, and the CakePHP community has just shown how strong it is, and that all parties are willing to cooperate for its prosperous future without leaving any hard feelings behind.&lt;/p&gt;

&lt;p&gt;Sincerely Yours,&lt;/p&gt;

&lt;p&gt;Felix Geisendörfer, Director&lt;br&gt;
Tim Koschützki, Director&lt;/p&gt;

&lt;p&gt;&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b743f89-ef24-4d73-9443-01a2cbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/e_ZPWdQ1uFw" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Thu, 11 Feb 2010 17:37:44 +0000</pubDate><comments>http://www.debuggable.com/posts/apology-to-the-csf-and-cakedc:4b743f89-ef24-4d73-9443-01a2cbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/apology-to-the-csf-and-cakedc:4b743f89-ef24-4d73-9443-01a2cbdd56cb</feedburner:origLink></item><item><title>Thank You!</title><link>http://feedproxy.google.com/~r/debuggable/~3/o_RKIjekU3c/thank-you:4b73ce12-d0c4-4620-a2fb-32a9cbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/thank-you:4b73ce12-d0c4-4620-a2fb-32a9cbdd56cb</guid><description>&lt;p&gt;&lt;strong&gt;Latest Update:&lt;/strong&gt; The whole situation has been resolved, please read &lt;a href="http://debuggable.com/posts/apology-to-the-csf-and-cakedc:4b743f89-ef24-4d73-9443-01a2cbdd56cb"&gt;our apology to the CSF and CakeDC&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are truly thankful. Since putting up our &lt;a href="http://debuggable.com/posts/the-high-cost-of-open-source:4b58e599-a9a0-4774-b3ff-302bcbdd56cb"&gt;post&lt;/a&gt; last night, people have already donated 2,075.00 EUR. There were almost 30 donators, some of them donating as much 600 EUR, with others who have pledged continuing support over the next months.&lt;/p&gt;

&lt;p&gt;We cannot thank everybody enough for this, and all the kind comments. But as a start, here is the list of people who have &lt;a href="http://pledgie.com/campaigns/8174"&gt;donated&lt;/a&gt; so far, we'll keep it updated. If you want your name to be linked, just email us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Garrett Woodworth&lt;/li&gt;
&lt;li&gt;Shawn Stratton&lt;/li&gt;
&lt;li&gt;Phillip Hile&lt;/li&gt;
&lt;li&gt;Aaron Forgue&lt;/li&gt;
&lt;li&gt;Rob Wilkerson&lt;/li&gt;
&lt;li&gt;Clay Loveless&lt;/li&gt;
&lt;li&gt;Gilles Grinfeder&lt;/li&gt;
&lt;li&gt;Jeff Loiselle&lt;/li&gt;
&lt;li&gt;Lars Schenk&lt;/li&gt;
&lt;li&gt;Nathan Abele&lt;/li&gt;
&lt;li&gt;@elventails&lt;/li&gt;
&lt;li&gt;@indiefan&lt;/li&gt;
&lt;li&gt;Yusuke Ando&lt;/li&gt;
&lt;li&gt;@jperras&lt;/li&gt;
&lt;li&gt;Jon Adams&lt;/li&gt;
&lt;li&gt;Jose Diaz-Gonzalez (@savant)&lt;/li&gt;
&lt;li&gt;Dirk Olbertz&lt;/li&gt;
&lt;li&gt;Mark Boas&lt;/li&gt;
&lt;li&gt;Charlie van de Kerkhof&lt;/li&gt;
&lt;li&gt;Lucian Lature&lt;/li&gt;
&lt;li&gt;@leomelzer&lt;/li&gt;
&lt;li&gt;Robert Scherer&lt;/li&gt;
&lt;li&gt;Guillaume Sautereau&lt;/li&gt;
&lt;li&gt;Daniel Hofstetter&lt;/li&gt;
&lt;li&gt;Arne Psczolla&lt;/li&gt;
&lt;li&gt;@pzwiers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regarding the question: Did we publish this to harm the CakePHP community?&lt;/p&gt;

&lt;p&gt;The answer is no, we are sorry if this shines a bad light on the project. We had two motivations to publish this post. For one, we wanted to reach out for help with this bill. However, we also wanted to share our story with the community, giving them the chance to push for improvements of the situation CakePHP is in.&lt;/p&gt;

&lt;p&gt;But you don't have to take our word for it. We already have a few new plugins &amp;amp; components lined up for release. This project has a community of great people, and just as they have supported us in this tough moment, we plan to continue supporting them.&lt;/p&gt;

&lt;p&gt;Again, thanks to everybody who helped, also those who are not involved with CakePHP at all!&lt;/p&gt;

&lt;p&gt;--fg&lt;/p&gt;

&lt;p&gt;&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b73ce12-d0c4-4620-a2fb-32a9cbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/o_RKIjekU3c" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Thu, 11 Feb 2010 10:07:29 +0000</pubDate><comments>http://www.debuggable.com/posts/thank-you:4b73ce12-d0c4-4620-a2fb-32a9cbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/thank-you:4b73ce12-d0c4-4620-a2fb-32a9cbdd56cb</feedburner:origLink></item><item><title>The High Cost of Open Source </title><link>http://feedproxy.google.com/~r/debuggable/~3/9xKJJQVhTuw/the-high-cost-of-open-source:4b58e599-a9a0-4774-b3ff-302bcbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/the-high-cost-of-open-source:4b58e599-a9a0-4774-b3ff-302bcbdd56cb</guid><description>&lt;p&gt;&lt;strong&gt;Latest Update:&lt;/strong&gt; The whole situation has been resolved, please read &lt;a href="http://debuggable.com/posts/apology-to-the-csf-and-cakedc:4b743f89-ef24-4d73-9443-01a2cbdd56cb"&gt;our apology to the CSF and CakeDC&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://debuggable.com/posts/summary_of_cakefest_3_berlin:4a5ca8fe-0f50-49fe-afc3-3d584834cda3"&gt;6 months ago, I posted about a great event&lt;/a&gt; which we helped to organize: CakeFest #3, here in our home city of Berlin. This event helped to connect developers from all over Europe, and even as far away as Australia, Tokyo and Los Angeles. There were great people, talks, and food, and everything ran extremely smoothly. By any measurement, it was a huge success.&lt;/p&gt;

&lt;p&gt;This did not happen by accident. A number of people made a big effort to put the event on, starting with lots of planning and communication months beforehand. Debuggable helped by finding and booking the venue, researching, and coordinating logistics here on location. We didn't make money from this, and that's okay. We wanted to support the CakePHP community by hosting another awesome event.&lt;/p&gt;

&lt;p&gt;Over 6 months later, &lt;a href="http://www.gls-german-courses.de/2013.html"&gt;the GLS&lt;/a&gt;, who provided us with first-class service and what was probably the best venue ever, has still not received payment.&lt;/p&gt;

&lt;p&gt;Don't be mistaken, this was not due to any errors in the organization of the event. The turnout was great, and the event was well-sponsored. The &lt;a href="http://cakefoundation.org/"&gt;Cake Software Foundation, Inc.&lt;/a&gt;, which collected all revenues, has already reimbursed its own organizing participants, but completely neglected to pay the venue (the bulk of the conference's expense). To make matters worse, the CSF has had their accounts frozen by the IRS.&lt;/p&gt;

&lt;p&gt;How do we know this? Unfortunately, we are in the middle of this mess. In our efforts to help organize the event, we signed the proposal for the location and catering. We did so in good faith, because we were working in cooperation with the CSF, and of course had all such details approved.&lt;/p&gt;

&lt;p&gt;When, in early October, we discovered that the venue never received payment, we initially believed it to be a mistake, and started delivering messages between the venue and &lt;a href="http://cakedc.com/eng/team#masters"&gt;Larry E. Masters&lt;/a&gt;, who in the meantime had taken over the position of CSF president after &lt;a href="http://twitter.com/gwoo"&gt;Garrett Woodworth&lt;/a&gt; had resigned. Larry told us he would take care of it.&lt;/p&gt;

&lt;p&gt;Weeks passed, and we talked to the GLS staff every other day, asking them for their patience, as there appeared to be "problems" with getting the payment sent. A month later, on November 10th, Larry agreed to send a token payment of USD $4500 through &lt;a href="http://cakedc.com/"&gt;the CakeDC&lt;/a&gt; via PayPal, which we forwarded to the venue (they do not accept PayPal).&lt;/p&gt;

&lt;p&gt;Unfortunately, this is still the latest update on the payment. Of the total invoice of EUR 7665, the first payment (after currency conversion and PayPal fees) only amounts to EUR 2807, leaving an outstanding balance of EUR 5058 (USD $6929).&lt;/p&gt;

&lt;p&gt;The venue has been incredibly patient and understanding through this whole process, but their patience has run out, and they're considering legal action against Debuggable. We signed the proposal, so technically they're not wrong: we are responsible.&lt;/p&gt;

&lt;p&gt;At this point it's pretty clear that the CSF has no intention of taking responsibility for this, which leaves us with some hard choices. We could argue that, by invoicing the CSF and not us, that the venue implicitly signed over the contract to the CSF. We have to admit, we briefly considered doing that. 5K is not pocket money for us, and this definitely isn't our bill.&lt;/p&gt;

&lt;p&gt;However, that would be wrong. Not to say that us paying this bill isn't wrong, but this is a wrong we can actually right. The venue deserves to get paid. So, we decided to go ahead and set up a plan to pay back the venue over the next few months.&lt;/p&gt;

&lt;p&gt;Since a few people who have been aware of the situation have asked us to provide a way for them to help, too, we have put up a page on pledgie.com:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://pledgie.com/campaigns/8174"&gt;Donate to the CakeFest Venue Payment&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We greatly appreciate any support, as it helps ease our burden, but the venue will be paid regardless of the outcome of the pledge. Right now, the most likely outcome is that we'll have to take care of this on our own, but we're still holding onto the hope that this last-ditch effort of going public might help change Larry's mind.&lt;/p&gt;

&lt;p&gt;What's worse is his company, &lt;a href="http://cakedc.com/"&gt;the CakeDC&lt;/a&gt;, now has exclusive controlling interest over a project which was once driven by its community. Despite his slowness to work this out with us, he has shown no hesitation in &lt;a href="http://www.pseudocoder.com/archives/cakephp-digest-21-whose-left"&gt;taking full advantage&lt;/a&gt; of the &lt;a href="http://cakephp.org/services/support"&gt;benefits of this control&lt;/a&gt;. If the CSF's position changes in any way, we will certainly send out an update.&lt;/p&gt;

&lt;p&gt;--fg&lt;/p&gt;

&lt;p&gt;PS: There is much more to this story, the CSF shake-ups, and why the their accounts are frozen, but it goes well beyond what we can verify. In the end, it doesn't matter; this isn't about finding fault, but about taking responsibility.
&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b58e599-a9a0-4774-b3ff-302bcbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/9xKJJQVhTuw" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Wed, 10 Feb 2010 19:58:14 +0000</pubDate><comments>http://www.debuggable.com/posts/the-high-cost-of-open-source:4b58e599-a9a0-4774-b3ff-302bcbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/the-high-cost-of-open-source:4b58e599-a9a0-4774-b3ff-302bcbdd56cb</feedburner:origLink></item><item><title>Unit testing with node.js</title><link>http://feedproxy.google.com/~r/debuggable/~3/E_zEOAy5VLs/unit-testing-with-node-js:4b647d40-34e4-435a-a880-3b04cbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/unit-testing-with-node-js:4b647d40-34e4-435a-a880-3b04cbdd56cb</guid><description>&lt;p&gt;Even so most stuff is fairly easy with &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt;, unit testing takes a little bit of getting used to. The main difference to regular unit testing is that just because your test finishes running without an error, it doesn't mean there was no problem. But lets start with the basics.&lt;/p&gt;

&lt;p&gt;Node.js has adopted the CommonJS &lt;a href="http://wiki.commonjs.org/wiki/Unit_Testing/1.0#Assert"&gt;assert module specification&lt;/a&gt;. You may also find references to &lt;code&gt;mjsunit&lt;/code&gt;, but node no longer uses this library. &lt;/p&gt;

&lt;p&gt;Lets have a look at how to write a basic test with node, lets call it &lt;code&gt;my-test.js&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="kw2"&gt;var&lt;/span&gt; assert = require&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'assert'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="co1"&gt;// Will pass&lt;/span&gt;&lt;br /&gt;
assert.&lt;span class="me1"&gt;ok&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;true&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="co1"&gt;// Will throw an exception&lt;/span&gt;&lt;br /&gt;
assert.&lt;span class="me1"&gt;ok&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;false&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Running this test will produce the following output:&lt;/p&gt;

&lt;pre class="terminal"&gt;$ node my-test.js
AssertionError: true == false
    at Object.&lt;anonymous&gt; (my-test.js:7:8)
    at [object Object].&lt;anonymous&gt; (node.js:928:23)
    at [object Object].emitSuccess (node.js:240:15)
    at [object Object].&lt;anonymous&gt; (node.js:653:21)
    at [object Object].emitSuccess (node.js:240:15)
    at node.js:510:29
    at node.js:985:1
    at node.js:989:1&lt;/pre&gt;

&lt;p&gt;One thing to note here is that, when node dies from an exception (which a failing assertion is), the exit code will be 1:&lt;/p&gt;

&lt;pre class="terminal"&gt;$ echo $?
1&lt;/pre&gt;

&lt;p&gt;But lets have a look at a more interesting unit test. Let's say you are writing a "hello world" web service called &lt;code&gt;hello.js&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="kw2"&gt;var&lt;/span&gt; http = require&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'http'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
exports.&lt;span class="me1"&gt;server&lt;/span&gt; = http.&lt;span class="me1"&gt;createServer&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;req, res&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; res.&lt;span class="me1"&gt;sendHeader&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="nu0"&gt;200&lt;/span&gt;, &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="st0"&gt;'Content-Type'&lt;/span&gt;: &lt;span class="st0"&gt;'text/plain'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; res.&lt;span class="me1"&gt;sendBody&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'hello world'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; res.&lt;span class="me1"&gt;finish&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;To test this service, we can write a file called &lt;code&gt;test-hello.js&lt;/code&gt; like this:&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="kw2"&gt;var&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; assert = require&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'assert'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; http = require&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'http'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; hello = require&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'./hello'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; callbackFired = &lt;span class="kw2"&gt;false&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
hello.&lt;span class="me1"&gt;server&lt;/span&gt;.&lt;span class="me1"&gt;listen&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="nu0"&gt;3000&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
http&lt;br /&gt;
&amp;nbsp; .&lt;span class="me1"&gt;cat&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'http://localhost:3000/'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; .&lt;span class="me1"&gt;addCallback&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;data&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; callbackFired = &lt;span class="kw2"&gt;true&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; assert.&lt;span class="me1"&gt;equal&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'hello world'&lt;/span&gt;, data&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; hello.&lt;span class="me1"&gt;server&lt;/span&gt;.&lt;span class="kw3"&gt;close&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
process.&lt;span class="me1"&gt;addListener&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'exit'&lt;/span&gt;, &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; assert.&lt;span class="me1"&gt;ok&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;callbackFired&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;What's important in this test is that we are checking for two things here.&lt;/p&gt;

&lt;p&gt;The first is the obvious assertion that the web service outputs the content we expect, nothing too exciting here.&lt;/p&gt;

&lt;p&gt;The second is declaring the variable &lt;code&gt;callbackFired&lt;/code&gt; and checking its value in the process &lt;code&gt;'exit'&lt;/code&gt; event. You could get away with not doing it for this particular test, because the test would never finish without the &lt;code&gt;hello.server.close()&lt;/code&gt; line getting executed. For more complex tests however, it becomes incredibly important to keep in mind that a callback may never fire, something you can only catch with little helper variables like this.&lt;/p&gt;

&lt;p&gt;If you need some more inspiration for testing different stuff with node, you should start by going over the &lt;a href="http://github.com/ry/node/tree/master/test/mjsunit/"&gt;test suite&lt;/a&gt; that comes with it.&lt;/p&gt;

&lt;p&gt;Let me know if you have any questions!&lt;/p&gt;

&lt;p&gt;-fg&lt;/p&gt;

&lt;p&gt;&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b647d40-34e4-435a-a880-3b04cbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/E_zEOAy5VLs" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Sat, 30 Jan 2010 18:41:42 +0000</pubDate><comments>http://www.debuggable.com/posts/unit-testing-with-node-js:4b647d40-34e4-435a-a880-3b04cbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/unit-testing-with-node-js:4b647d40-34e4-435a-a880-3b04cbdd56cb</feedburner:origLink></item><item><title>Git Fake Submodules</title><link>http://feedproxy.google.com/~r/debuggable/~3/0GjYnS3osMo/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb</guid><description>&lt;p&gt;Git submodules suck. They are a pain to use, difficult to explain and you cannot check out partial trees. The later is an inherent limitation of git, but I have a fix for the rest.&lt;/p&gt;

&lt;p&gt;Meet fake submodules. The idea is simple, instead of using actual submodules, you just trick git into thinking the files belong to the main repository while having the respective sub-dirs remain independent clones. Doing that is simple:&lt;/p&gt;

&lt;pre class="terminal"&gt;
$ cd my-project
$ git clone &amp;lt;subproject-url&amp;gt; my-subproject
$ git add my-subproject/
&lt;/pre&gt;

&lt;p&gt;The important part is the "/" (slash) at the end of the last command. If you omit that, git will automatically assume you want to add 'my-subproject' as a submodule. But if you don't, git just sees the files in the sub-directory and ignores that fact that its a git-repo of its own.&lt;/p&gt;

&lt;p&gt;The cool thing is that you can now update a fake sub-module to the latest version as simple as:&lt;/p&gt;

&lt;pre class="terminal"&gt;
$ cd my-subproject
$ git pull
&lt;/pre&gt;

&lt;p&gt;This works because when you are inside &lt;code&gt;my-subproject&lt;/code&gt;, git uses the '.git' folder closest to it which is &lt;code&gt;my-subproject/.git&lt;/code&gt;. If the sub project is your own, you could even push your changes to it upstream without changing projects.&lt;/p&gt;

&lt;p&gt;Now as far as collaboration is concerned, none of your collaborators will have a clue about your fake submodules. All they will see is some code in some folder. They will not be able to go into the &lt;code&gt;my-subproject&lt;/code&gt; folder and git pull on it. However, if they need to do that, they can just &lt;code&gt;rm -rf my-subproject&lt;/code&gt; and replace it with a clone themselves.&lt;/p&gt;

&lt;p&gt;To me this is a pretty perfect &amp;amp; easy solution. I mostly use it for CakePHP plugins &amp;amp; node.js modules I am working on, but it works just as great with other peoples code you want to depend on. You can even apply hacks against their code, have them in your main repository, and make sure they stay applied on top by using 'git pull --rebase' when updating the sub project.&lt;/p&gt;

&lt;p&gt;Let me know what you think!&lt;/p&gt;

&lt;p&gt;--fg
&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b563ee4-f3cc-4061-967e-0e48cbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/0GjYnS3osMo" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Wed, 20 Jan 2010 14:07:44 +0000</pubDate><comments>http://www.debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb</feedburner:origLink></item><item><title>JavaScript Meetup Berlin + Slides</title><link>http://feedproxy.google.com/~r/debuggable/~3/ck1Kp3rFFxs/javascript-meetup-berlin-slides:4b4d98bc-034c-451d-b8f1-5377cbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/javascript-meetup-berlin-slides:4b4d98bc-034c-451d-b8f1-5377cbdd56cb</guid><description>&lt;p&gt;Last night I had the opportunity to speak about &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt; at the &lt;a href="http://nodejs.org/"&gt;first&lt;/a&gt; Berlin JavaScript user group meeting. I'm really thankful to &lt;a href="https://twitter.com/rmehner"&gt;Robin Mehner&lt;/a&gt;, &lt;a href="https://twitter.com/janl"&gt;Jan Lehnardt&lt;/a&gt; and the awesome people at &lt;a href="http://upstre.am/"&gt;upstream&lt;/a&gt; and &lt;a href="http://co-up.de/"&gt;co-up&lt;/a&gt; for organizing the event and hopefully many to follow.&lt;/p&gt;

&lt;p&gt;Anyway, here are the slides:&lt;/p&gt;

&lt;div style="width:425px;text-align:left" id="__ss_2902114"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/the_undefined/nodejs-a-quick-tour" title="Node.js - A Quick Tour"&gt;Node.js - A Quick Tour&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=nodejs-a-quick-tour-100113034656-phpapp01&amp;stripped_title=nodejs-a-quick-tour" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=nodejs-a-quick-tour-100113034656-phpapp01&amp;stripped_title=nodejs-a-quick-tour" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/the_undefined"&gt;Felix Geisendörfer&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also &lt;a href="http://felixge.s3.amazonaws.com/10/nodejs-a-quick-tour.pdf"&gt;download them as PDF&lt;/a&gt; (344 kb).&lt;/p&gt;

&lt;p&gt;The meetup itself was rather awesome. ~35 people showed up with many coming from different backgrounds (Rails, Symfony, Zend, Python, ...) united by their interest in JavaScript.&lt;/p&gt;

&lt;p&gt;-- fg&lt;/p&gt;

&lt;p&gt;&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b4d98bc-034c-451d-b8f1-5377cbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/ck1Kp3rFFxs" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Wed, 13 Jan 2010 10:08:46 +0000</pubDate><comments>http://www.debuggable.com/posts/javascript-meetup-berlin-slides:4b4d98bc-034c-451d-b8f1-5377cbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/javascript-meetup-berlin-slides:4b4d98bc-034c-451d-b8f1-5377cbdd56cb</feedburner:origLink></item><item><title>CakePHP Authsome - Debuggable's Xmas Gift</title><link>http://feedproxy.google.com/~r/debuggable/~3/W7tgUIpw42w/cakephp-authsome-debuggable-s-xmas-gift:4b34b4e6-9ca4-4673-bea6-4776cbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/cakephp-authsome-debuggable-s-xmas-gift:4b34b4e6-9ca4-4673-bea6-4776cbdd56cb</guid><description>&lt;p&gt;Merry Xmas everybody. We hope you are having a lovely time and get to renew the batteries for an awesome 2010 over the holidays.&lt;/p&gt;

&lt;p&gt;To ease the withdrawal symptoms, Tim and I decided to do some light development over the holidays in order to create a little Xmas gift for the CakePHP community:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/felixge/cakephp-authsome"&gt;The Authsome plugin&lt;/a&gt;: Authentication for people who hate the AuthComponent.&lt;/p&gt;

&lt;p&gt;We have been using a system very similar to Authsome for all our CakePHP projects over the years, but it wasn't until now that we had a chance to properly decouple it from the individual projects we used it in. A big thanks for that goes to &lt;a href="http://threeleaf.tv/"&gt;ThreeLeaf Creative&lt;/a&gt;, the makers of a fantastic CakePHP CMS system who paid for the refactoring.&lt;/p&gt;

&lt;p&gt;Next on the radar is Righteful: Acl for people who hate the Acl component. We hope to have it ready at some point early next year.&lt;/p&gt;

&lt;p&gt;Alright, so go ahead and &lt;a href="http://github.com/felixge/cakephp-authsome"&gt;read the authsome docs&lt;/a&gt; over at Github and let us know what you think.&lt;/p&gt;

&lt;p&gt;Merry Xmas,&lt;/p&gt;

&lt;p&gt;-- Tim &amp;amp; Felix
&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b34b4e6-9ca4-4673-bea6-4776cbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/W7tgUIpw42w" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Fri, 25 Dec 2009 12:49:42 +0000</pubDate><comments>http://www.debuggable.com/posts/cakephp-authsome-debuggable-s-xmas-gift:4b34b4e6-9ca4-4673-bea6-4776cbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/cakephp-authsome-debuggable-s-xmas-gift:4b34b4e6-9ca4-4673-bea6-4776cbdd56cb</feedburner:origLink></item><item><title>RightJS 1.5: 6-8 times faster than jQuery</title><link>http://feedproxy.google.com/~r/debuggable/~3/iEo_go_w8sw/rightjs-1-5-6-8-times-faster-than-jquery:4b1fc009-1940-4d26-bdc6-0af2cbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/rightjs-1-5-6-8-times-faster-than-jquery:4b1fc009-1940-4d26-bdc6-0af2cbdd56cb</guid><description>&lt;p&gt;My journey of &lt;a href="http://www.structuredprocrastination.com/"&gt;mastering procrastination&lt;/a&gt; has led me to an interesting article on Hacker News today:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://news.ycombinator.com/item?id=985723"&gt;RightJS 1.5: 6-8 times faster than jQuery&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(The title has been updated to "RightJS Version 1.5.0 Is Out" since I started writing this.)&lt;/p&gt;

&lt;p&gt;Wow, I thought! This sounds like an excellent example of cargo cult science, one of my favourite subjects.&lt;/p&gt;

&lt;p&gt;I mean I love innovation in this field just like everybody else. But seriously, jQuery is not exactly know for being slow &amp;amp; heavy. So anybody claiming a 6-8x speed improvement must have achieved an unbelievable breakthrough. Either that, or he must be using using the cargo cult method.&lt;/p&gt;

&lt;p&gt;Applying the cargo cult method to performance testing is rather simple, which probably explains its popularity. You pick a random series of tests that can be run against the various implementations you want to compete with. Then you spend a few hours hacking away at your implementation until it is the clear winner. Don't give up if it becomes too hard, just tweak the test cases to slightly favor your implementation. It's really as easy as that.&lt;/p&gt;

&lt;p&gt;I can totally understand why people are doing that. The opposite would mean that you have to apply the scientific method, which is really cumbersome. First you have to collect data, lots of it. In our case that means performing very detailed analysis and profiling of a large enough set of real world JavaScript applications. Using this data set, you should be able to answer questions like: What are the most common selectors people use? What DOM operations are popular? Which of those are actually relevant to the performance of the analyzed applications? With those answers you can attempt to come up with a series of tests that will rank the various implementations according to their performance. But actually writing those tests will be very hard. Should you use the most distinct and sexy way in each implementation? Or should you use the most effective techniques people have come up with?&lt;/p&gt;

&lt;p&gt;Luckily there is a third option. It is called specialized benchmarking. You start by admitting that the things you are going to test are purely based on your curiosity about them, possibly because they are related to the particular problem YOU care about. Make it very clear that the outcome of those tests should in no way be seen as an indicator for overall performance and try to hide them from people who don't know what that means.&lt;/p&gt;

&lt;p&gt;Specialized benchmarking will possibly not answer anybodies questions other than your own, but it beats the hell out of the cargo cult method.&lt;/p&gt;

&lt;p&gt;Let's examine why the RightJS performance tests get it wrong and what they could do about it. From this point on I will only refer to material on their page, the post on Hacker News was just how I heard about them.&lt;/p&gt;

&lt;p&gt;First of all, they claim that their performance benchmarks are there "To give you some ideas about the project quality and abilities". I think that should be changed to: "We are especially fast for the following operations (...), those however are not proofen to be good indicators for general performance in JS projects.". It's kind of like weight loss advertisement. You can show pictures of people who lost 50 pound, but you gotta put that "* Results are not typical" note there. This way people can pause for a second, and remember that there are no magic bullets to weight loss and consider their purchase with that in mind.&lt;/p&gt;

&lt;p&gt;After that, they could start to decide whether some of their tests are worth keeping, and if so, make sure that they are as scientific as possible. I'll just use their test #1 as an example, but check the &lt;a href="http://github.com/MadRabbit/taskspeed/tree/master/tests/"&gt;test suite&lt;/a&gt; for yourself, to see that this pattern is repeated throughout the entire thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing jQuery DOM building (343ms*):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="st0"&gt;&amp;quot;make&amp;quot;&lt;/span&gt;: &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;for&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;var&lt;/span&gt; i = &lt;span class="nu0"&gt;0&lt;/span&gt;; i&amp;lt;&lt;span class="nu0"&gt;250&lt;/span&gt;; i++&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; $&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;&amp;lt;ul id='setid&amp;quot;&lt;/span&gt; + i + &lt;span class="st0"&gt;&amp;quot;' class='fromcode'&amp;gt;&amp;lt;/ul&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;append&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;one&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;append&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;two&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;append&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;three&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;appendTo&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;body&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;return&lt;/span&gt; $&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;ul.fromcode&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;length&lt;/span&gt;;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing RightJS DOM building (80ms*):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="st0"&gt;&amp;quot;make&amp;quot;&lt;/span&gt; : &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;for&lt;/span&gt; &lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;var&lt;/span&gt; i = &lt;span class="nu0"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span class="nu0"&gt;250&lt;/span&gt;; i++&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; document.&lt;span class="me1"&gt;body&lt;/span&gt;.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="kw2"&gt;new&lt;/span&gt; Element&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'ul'&lt;/span&gt;, &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;'class'&lt;/span&gt;: &lt;span class="st0"&gt;'fromcode'&lt;/span&gt;, id: &lt;span class="st0"&gt;'setid'&lt;/span&gt;+i&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;insert&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="kw2"&gt;new&lt;/span&gt; Element&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'li'&lt;/span&gt;, &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;html: &lt;span class="st0"&gt;'one'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="kw2"&gt;new&lt;/span&gt; Element&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'li'&lt;/span&gt;, &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;html: &lt;span class="st0"&gt;'two'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="kw2"&gt;new&lt;/span&gt; Element&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'li'&lt;/span&gt;, &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;html: &lt;span class="st0"&gt;'three'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#93;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;return&lt;/span&gt; $$&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'ul.fromcode'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;length&lt;/span&gt;;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;I smell cargo! First of all, why is RightJS using a native DOM method, document.body.appendChild, and jQuery has to use .appendTo('body')? Those are two radically different operations, and just to see how radical lets make the following change:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimized jQuery DOM building I (194ms*):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="st0"&gt;&amp;quot;make&amp;quot;&lt;/span&gt;: &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;for&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;var&lt;/span&gt; i = &lt;span class="nu0"&gt;0&lt;/span&gt;; i&amp;lt;&lt;span class="nu0"&gt;250&lt;/span&gt;; i++&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; document.&lt;span class="me1"&gt;body&lt;/span&gt;.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; $&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;&amp;lt;ul id='setid&amp;quot;&lt;/span&gt; + i + &lt;span class="st0"&gt;&amp;quot;' class='fromcode'&amp;gt;&amp;lt;/ul&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;append&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;one&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;append&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;two&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;append&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;three&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;&lt;span class="nu0"&gt;0&lt;/span&gt;&lt;span class="br0"&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;return&lt;/span&gt; $&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;ul.fromcode&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;length&lt;/span&gt;;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Ouch, an error rate of 43% against jQuery. Let's try harder:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimized jQuery DOM building II (72ms*):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="st0"&gt;&amp;quot;make&amp;quot;&lt;/span&gt;: &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;for&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;var&lt;/span&gt; i = &lt;span class="nu0"&gt;0&lt;/span&gt;; i&amp;lt;&lt;span class="nu0"&gt;250&lt;/span&gt;; i++&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; document.&lt;span class="me1"&gt;body&lt;/span&gt;.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; $&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;ul id='setid&amp;quot;&lt;/span&gt; + i + &lt;span class="st0"&gt;&amp;quot;' class='fromcode'&amp;gt;&amp;quot;&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;one&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;two&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;three&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;&lt;span class="nu0"&gt;0&lt;/span&gt;&lt;span class="br0"&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;return&lt;/span&gt; $&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;ul.fromcode&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;length&lt;/span&gt;;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;If this was a presentation I would have an LOLCat saying "jQuery rulez" right now. But luckily this isn't and I'll try to reason scientifically about this.&lt;/p&gt;

&lt;p&gt;jQuery is NOT faster in this example. Don't believe the numbers you see. They have been meaningless all along. The reason for that is simple: While initially it looked like we were performing the same test with jQuery as we were with RightJS, we never actually did! The jQuery example, from the beginning, was creating DOM elements from HTML strings, while RightJS was wrapping the document.createElement API. This is not the same thing and you cannot learn anything from comparing apples to oranges.&lt;/p&gt;

&lt;p&gt;The truth as far as this test case is concerned? Well, jQuery simply does not have a document.createElement wrapper. Thus you cannot compare it to implementations that do. And why should you? DOM building like this is largely useless, given excellent alternatives such as &lt;a href="http://ejohn.org/blog/javascript-micro-templating/"&gt;John' Micro -Templating&lt;/a&gt; engine.&lt;/p&gt;

&lt;p&gt;Just to show how useless this test was from the beginning, here is my not so paradox implementation that outperforms the pure DOM test:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing Pure DOM building (37ms*):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="st0"&gt;&amp;quot;make&amp;quot;&lt;/span&gt;: &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="kw1"&gt;for&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;var&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; body = document.&lt;span class="me1"&gt;body&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ul = document.&lt;span class="me1"&gt;createElement&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; li = document.&lt;span class="me1"&gt;createElement&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;li&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; i = &lt;span class="nu0"&gt;0&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fromcode;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; i &amp;lt; &lt;span class="nu0"&gt;250&lt;/span&gt;; ++i&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fromcode &amp;nbsp; &amp;nbsp;= ul.&lt;span class="me1"&gt;cloneNode&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;true&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fromcode.&lt;span class="me1"&gt;id&lt;/span&gt; = &lt;span class="st0"&gt;&amp;quot;setid&amp;quot;&lt;/span&gt; + i;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fromcode.&lt;span class="me1"&gt;className&lt;/span&gt; = &lt;span class="st0"&gt;&amp;quot;fromcode&amp;quot;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fromcode.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;li.&lt;span class="me1"&gt;cloneNode&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;true&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;document.&lt;span class="me1"&gt;createTextNode&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fromcode.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;li.&lt;span class="me1"&gt;cloneNode&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;true&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;document.&lt;span class="me1"&gt;createTextNode&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;two&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fromcode.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;li.&lt;span class="me1"&gt;cloneNode&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;true&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;document.&lt;span class="me1"&gt;createTextNode&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;three&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; body.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;fromcode&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="kw1"&gt;return&lt;/span&gt; &amp;nbsp;utility.&lt;span class="me1"&gt;getSimple&lt;/span&gt;.&lt;span class="me1"&gt;call&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;body, &lt;span class="st0"&gt;&amp;quot;ul.fromcode&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;length&lt;/span&gt;;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimized jQuery DOM building III (36ms*):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="st0"&gt;&amp;quot;make&amp;quot;&lt;/span&gt;: &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw2"&gt;var&lt;/span&gt; elements = &lt;span class="st0"&gt;'&amp;lt;div&amp;gt;'&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;for&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;var&lt;/span&gt; i = &lt;span class="nu0"&gt;0&lt;/span&gt;; i&amp;lt;&lt;span class="nu0"&gt;250&lt;/span&gt;; i++&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; elements = elements+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;ul id='setid&amp;quot;&lt;/span&gt; + i + &lt;span class="st0"&gt;&amp;quot;' class='fromcode'&amp;gt;&amp;quot;&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;one&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;two&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;li&amp;gt;three&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;&amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; $&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;elements+&lt;span class="st0"&gt;'&amp;lt;/div&amp;gt;'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;children&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; .&lt;span class="me1"&gt;each&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; document.&lt;span class="me1"&gt;body&lt;/span&gt;.&lt;span class="me1"&gt;appendChild&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw1"&gt;this&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;return&lt;/span&gt; $&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;ul.fromcode&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;length&lt;/span&gt;;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the cargo cult method is quite powerful : ).&lt;/p&gt;

&lt;p&gt;Anyway, I don't want to discourage the development of RightJS in any way. I think it's awesome that there are libraries that are trying to compete with jQuery.&lt;/p&gt;

&lt;p&gt;It is really hard to do meaningful performance testing and infinitely easy for some random punk like me to come along and point out all the flaws. To me, even trying to do a general purpose performance test against 6 (!) implementations, that is pure bravery. So in case you decide to do something similar, just admit the odds you are up against and people will be very forgiving and engaged.&lt;/p&gt;

&lt;p&gt;Comments, hate mail &amp;amp; suggestions are welcome!&lt;/p&gt;

&lt;p&gt;-- Felix Geisendörfer aka the_undefined&lt;/p&gt;

&lt;p&gt;&amp;#42; Results not typical - Some recent version of Firefox on my Laptop, picking random samples from runs that looked good!
&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b1fc009-1940-4d26-bdc6-0af2cbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/iEo_go_w8sw" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Wed, 09 Dec 2009 17:16:48 +0000</pubDate><comments>http://www.debuggable.com/posts/rightjs-1-5-6-8-times-faster-than-jquery:4b1fc009-1940-4d26-bdc6-0af2cbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/rightjs-1-5-6-8-times-faster-than-jquery:4b1fc009-1940-4d26-bdc6-0af2cbdd56cb</feedburner:origLink></item><item><title>Parsing form data with node.js</title><link>http://feedproxy.google.com/~r/debuggable/~3/uCQICffng5g/parsing-a-form-in-node-js-1:4b0bff13-4244-4ebc-8455-4975cbdd56cb</link><guid isPermaLink="false">http://www.debuggable.com/posts/parsing-a-form-in-node-js-1:4b0bff13-4244-4ebc-8455-4975cbdd56cb</guid><description>&lt;p&gt;Many people asked about form parsing in #node.js after the &lt;a href="http://search.twitter.com/search?q=node.js"&gt;initial buzz-wave&lt;/a&gt; yesterday.&lt;/p&gt;

&lt;p&gt;Right now node does not include a parser for regular form data (application/x-www-form-urlencoded). However, you can use the http multipart parser to achieve the same thing.&lt;/p&gt;

&lt;p&gt;Here is a bare-bone example for that:&lt;/p&gt;

&lt;p&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="code debuggable_sh_js" style="white-space: wrap;white-space: nowrap;"&gt;
&lt;span class="kw2"&gt;var&lt;/span&gt; http = require&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'http'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class="kw2"&gt;var&lt;/span&gt; multipart = require&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'multipart'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class="kw2"&gt;var&lt;/span&gt; sys = require&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'sys'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="kw2"&gt;var&lt;/span&gt; server = http.&lt;span class="me1"&gt;createServer&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;req, res&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class="kw1"&gt;switch&lt;/span&gt; &lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;req.&lt;span class="me1"&gt;uri&lt;/span&gt;.&lt;span class="me1"&gt;path&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="st0"&gt;'/'&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; res.&lt;span class="me1"&gt;sendHeader&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="nu0"&gt;200&lt;/span&gt;, &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="st0"&gt;'Content-Type'&lt;/span&gt;: &lt;span class="st0"&gt;'text/html'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; res.&lt;span class="me1"&gt;sendBody&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;'&amp;lt;form action=&amp;quot;/myaction&amp;quot; method=&amp;quot;post&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;'&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;'&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;field1&amp;quot;&amp;gt;'&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;'&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;field2&amp;quot;&amp;gt;'&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;'&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;'&lt;/span&gt;+&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="st0"&gt;'&amp;lt;/form&amp;gt;'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; res.&lt;span class="me1"&gt;finish&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="kw1"&gt;break&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class="kw1"&gt;case&lt;/span&gt; &lt;span class="st0"&gt;'/myaction'&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; multipart.&lt;span class="me1"&gt;parse&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;req&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;.&lt;span class="me1"&gt;addCallback&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;parts&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; res.&lt;span class="me1"&gt;sendHeader&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="nu0"&gt;200&lt;/span&gt;, &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="st0"&gt;'Content-Type'&lt;/span&gt;: &lt;span class="st0"&gt;'text/plain'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; res.&lt;span class="me1"&gt;sendBody&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;sys.&lt;span class="me1"&gt;inspect&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;parts&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; res.&lt;span class="me1"&gt;finish&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="kw1"&gt;break&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
server.&lt;span class="me1"&gt;listen&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="nu0"&gt;8000&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Run this code and point your browser to http://localhost:8000/. You will be presented with a form, and when you submit it, you will see the contents of the POST as JSON. For more information check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://nodejs.org/api.html#_multipart_parsing"&gt;The multipart documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://debuggable.com/posts/streaming-file-uploads-with-node-js:4ac094b2-b6c8-4a7f-bd07-28accbdd56cb"&gt;My tutorial on streaming file uploads with node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is specifying the enctype of your form as "multipart/form-data".&lt;/p&gt;

&lt;p&gt;If you need to parse regular form data, have a look at sixtus &lt;a href="http://github.com/sixtus/coltrane/blob/master/module/www-forms.js"&gt;www-forms&lt;/a&gt; module. Chances are good a module like this, with a similar API to the multipart parser, will make it into the core at some point (patches are welcome).&lt;/p&gt;

&lt;p&gt;HTH,&lt;br&gt;
-- Felix Geisendörfer aka the_undefined&lt;/p&gt;

&lt;p&gt;&lt;img style="display: none;" src="http://www.debuggable.com/posts/tick/4b0bff13-4244-4ebc-8455-4975cbdd56cb"&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/debuggable/~4/uCQICffng5g" height="1" width="1"/&gt;</description><author>felix@debuggable.com</author><pubDate>Tue, 24 Nov 2009 15:43:15 +0000</pubDate><comments>http://www.debuggable.com/posts/parsing-a-form-in-node-js-1:4b0bff13-4244-4ebc-8455-4975cbdd56cb</comments><feedburner:origLink>http://www.debuggable.com/posts/parsing-a-form-in-node-js-1:4b0bff13-4244-4ebc-8455-4975cbdd56cb</feedburner:origLink></item></channel></rss>
