<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-34049130</id><updated>2012-01-26T07:56:30.689+01:00</updated><category term='ruby'/><category term='mind'/><category term='scheme'/><category term='linq'/><category term='scala'/><category term='javascript'/><category term='books'/><category term='patterns'/><category term='dynamic'/><category term='smalltalk'/><category term='programming'/><category term='tutorial'/><category term='maven'/><category term='conference'/><category term='presentation'/><category term='c#'/><category term='exceptions'/><category term='jquery'/><category term='node'/><category term='mastery'/><category term='git'/><category term='wpf'/><category term='rails'/><category term='haskell'/><category term='nodejs'/><category term='css webkit'/><category term='design'/><category term='oopsla'/><category term='quick-reference'/><category term='methods'/><category term='summary'/><category term='coffeescript'/><category term='rant'/><category term='notes'/><title type='text'>The Tapir's Tale</title><subtitle type='html'>Programming, philosophy, recursion, infinity and the mind.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://anders.janmyr.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default?start-index=101&amp;max-results=100'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>108</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-34049130.post-7807098460042512358</id><published>2012-01-25T17:18:00.000+01:00</published><updated>2012-01-25T17:18:34.955+01:00</updated><title type='text'>Finding with Git</title><content type='html'>&lt;p&gt;Git is an amazing version control system that never loses anything, but
sometimes it can be hard to find out where things are. Most of the time
it is going to be &lt;code&gt;git log&lt;/code&gt; that is our friend, but not all the time.&lt;/p&gt;

&lt;h2&gt;Where is my file?&lt;/h2&gt;

&lt;p&gt;Sometimes you know that you have a file in your repository but, you
don&amp;#39;t know exactly where it is. &lt;code&gt;git ls-files&lt;/code&gt; is the answer.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Find all files with the name security in the path.&lt;/font&gt;&lt;/i&gt;
$ git ls-files &lt;font color="#990000"&gt;|&lt;/font&gt; grep security
lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js
test/security-test&lt;font color="#990000"&gt;.&lt;/font&gt;js
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Obviously, you can use any particular &lt;code&gt;grep&lt;/code&gt; options you prefer, like &lt;code&gt;-i&lt;/code&gt;
to ignore case.&lt;/p&gt;

&lt;h2&gt;In what files does &lt;em&gt;word&lt;/em&gt; exist?&lt;/h2&gt;

&lt;p&gt;If you want to find information inside files &lt;code&gt;git grep&lt;/code&gt; is your friend.
&lt;code&gt;git grep&lt;/code&gt; works similar to a recursive grep &lt;code&gt;grep -r .&lt;/code&gt; but it only
searches files that are managed by git.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Find all lines matching *crypt* in current version.&lt;/font&gt;&lt;/i&gt;
$ git grep crypt
lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js&lt;font color="#990000"&gt;:&lt;/font&gt;var crypto &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'crypto'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js&lt;font color="#990000"&gt;:&lt;/font&gt;   var hmac &lt;font color="#990000"&gt;=&lt;/font&gt; crypto&lt;font color="#990000"&gt;.&lt;/font&gt;createHmac&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'sha256'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; key&lt;font color="#990000"&gt;);&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Also give me the line numbers&lt;/font&gt;&lt;/i&gt;
 git grep -n crypt
lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;var crypto &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'crypto'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;15&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;   var hmac &lt;font color="#990000"&gt;=&lt;/font&gt; crypto&lt;font color="#990000"&gt;.&lt;/font&gt;createHmac&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'sha256'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; key&lt;font color="#990000"&gt;);&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# List only the file names&lt;/font&gt;&lt;/i&gt;
 git grep -l crypt
lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js

&lt;i&gt;&lt;font color="#9A1900"&gt;# Also list how many times (count) it matched.&lt;/font&gt;&lt;/i&gt;
$ git grep -c crypt
lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;It is also possible to give versions to &lt;code&gt;grep&lt;/code&gt; to find out what has
changed between revisions.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Find all files with lines matching *type* in revisions `master` and `8f0fb7f`.&lt;/font&gt;&lt;/i&gt;
git grep -l &lt;b&gt;&lt;font color="#0000FF"&gt;type&lt;/font&gt;&lt;/b&gt;  master 8f0fb7f
master&lt;font color="#990000"&gt;:&lt;/font&gt;lib/dynamo-db/index&lt;font color="#990000"&gt;.&lt;/font&gt;js
master&lt;font color="#990000"&gt;:&lt;/font&gt;lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js
master&lt;font color="#990000"&gt;:&lt;/font&gt;package&lt;font color="#990000"&gt;.&lt;/font&gt;json
8f0fb7f&lt;font color="#990000"&gt;:&lt;/font&gt;lib/dynamo-db/index&lt;font color="#990000"&gt;.&lt;/font&gt;js
8f0fb7f&lt;font color="#990000"&gt;:&lt;/font&gt;package&lt;font color="#990000"&gt;.&lt;/font&gt;json
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Maybe this is not that impressive. Most of the above can be accomplished
with standard &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;ack&lt;/code&gt;, and friends. But Git is a version
control system. How do I find out about things that happened in the past?&lt;/p&gt;

&lt;h2&gt;Who deleted my file?&lt;/h2&gt;

&lt;p&gt;You know how it is, you are working in some project and, your dog gets
sick and you have to stay home from work, when you come back someone has
deleted your file! Where is it and who did it? &lt;code&gt;git log&lt;/code&gt; to the rescue.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git log&lt;/code&gt; shows you the commit logs. It is your eye into the past.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# When (in what commit) was my file deleted?&lt;/font&gt;&lt;/i&gt;
$ git log --diff-filter&lt;font color="#990000"&gt;=&lt;/font&gt;D -- test/create-table-test&lt;font color="#990000"&gt;.&lt;/font&gt;js
commit ba6c4d8bc165b8fb8208979c3e5513bd53477d51
Author&lt;font color="#990000"&gt;:&lt;/font&gt; Anders Janmyr &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;anders@janmyr&lt;font color="#990000"&gt;.&lt;/font&gt;com&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt;
Date&lt;font color="#990000"&gt;:&lt;/font&gt;   Wed Jan &lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;09&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;46&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#993399"&gt;2012&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;

    Removed the stupid failing &lt;b&gt;&lt;font color="#0000FF"&gt;test&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Looks like I found the culprit, was I working from home? But is the file
really deleted here. To get some more information about files add the
&lt;code&gt;--summary&lt;/code&gt; option.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# When (in what commit) was my file deleted?&lt;/font&gt;&lt;/i&gt;
$ git log --diff-filter&lt;font color="#990000"&gt;=&lt;/font&gt;D --summary -- test/create-table-test&lt;font color="#990000"&gt;.&lt;/font&gt;js
commit ba6c4d8bc165b8fb8208979c3e5513bd53477d51
Author&lt;font color="#990000"&gt;:&lt;/font&gt; Anders Janmyr &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;anders@janmyr&lt;font color="#990000"&gt;.&lt;/font&gt;com&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt;
Date&lt;font color="#990000"&gt;:&lt;/font&gt;   Wed Jan &lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;09&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;46&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#993399"&gt;2012&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;

    Removed the stupid failing &lt;b&gt;&lt;font color="#0000FF"&gt;test&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;

 delete mode &lt;font color="#993399"&gt;100644&lt;/font&gt; test/create-table-test&lt;font color="#990000"&gt;.&lt;/font&gt;js
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Yes, it looks like the file is really deleted. Stupid bastard! Let me
break this command down starting with the last command.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;test/create-table-test.js&lt;/code&gt; - The filename has to be the relative path
to the file (from your current directory).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--&lt;/code&gt; - The double-dash is used to tell Git that this is not a branch
or an option.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--summary&lt;/code&gt; - Show me what files were deleted or added.
&lt;code&gt;--name-status&lt;/code&gt; is similar.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--diff-filter&lt;/code&gt; - This is a real beauty, it allows me to limit the log
to show me only the specified kind of change, in this case &lt;code&gt;D&lt;/code&gt;, for
Deleted. Other options are: Added (A), Copied (C), Modified (M) and Renamed (R)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;When was a file added?&lt;/h2&gt;

&lt;p&gt;This uses the same technique as above, but I will vary it since I don&amp;#39;t
want to type the full path of the file.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Find out when the integration tests where added.&lt;/font&gt;&lt;/i&gt;
$ git log --diff-filter&lt;font color="#990000"&gt;=&lt;/font&gt;A --name-status &lt;font color="#990000"&gt;|&lt;/font&gt;grep -C &lt;font color="#993399"&gt;6&lt;/font&gt; integ
commit 09420cfea8c7b569cd47f690104750fec358a10a
Author&lt;font color="#990000"&gt;:&lt;/font&gt; Anders Janmyr &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;anders@janmyr&lt;font color="#990000"&gt;.&lt;/font&gt;com&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt;
Date&lt;font color="#990000"&gt;:&lt;/font&gt;   Tue Jan &lt;font color="#993399"&gt;24&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#993399"&gt;2012&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;

    Extracted integration &lt;b&gt;&lt;font color="#0000FF"&gt;test&lt;/font&gt;&lt;/b&gt;

A integration-test/sts-test&lt;font color="#990000"&gt;.&lt;/font&gt;js

commit 205db3965dec6c2c4c7b2bb75387a591d49e1951
Author&lt;font color="#990000"&gt;:&lt;/font&gt; Anders Janmyr &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;anders@janmyr&lt;font color="#990000"&gt;.&lt;/font&gt;com&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt;
Date&lt;font color="#990000"&gt;:&lt;/font&gt;   Sat Jan &lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;03&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;59&lt;/font&gt; &lt;font color="#993399"&gt;2012&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;As you can see here I am using &lt;code&gt;--name-status&lt;/code&gt; as a variation on
&lt;code&gt;--summary&lt;/code&gt;, it uses the same notation as the &lt;code&gt;--diff-filter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I am using &lt;code&gt;grep -C 6&lt;/code&gt; to get some context around the found element, in
this case six lines before and after the match. Very useful!&lt;/p&gt;

&lt;h2&gt;Who changed that line?&lt;/h2&gt;

&lt;p&gt;As you probably know it is to see who has done something in a file by
using &lt;code&gt;git blame&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ git blame test/security-test&lt;font color="#990000"&gt;.&lt;/font&gt;js
205db396 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;03&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;59&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var vows &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'vows'&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt;
205db396 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;03&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;59&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;     assert &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'assert'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
205db396 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;03&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;59&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
09420cfe &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;24&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var access &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;'access'&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
09420cfe &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;24&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;5&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var secret &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;'secret'&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
90b65208 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;11&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;58&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;6&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
205db396 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;03&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;59&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;7&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var security &lt;font color="#990000"&gt;=&lt;/font&gt; new Security&lt;font color="#990000"&gt;(&lt;/font&gt;{
90b65208 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;11&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;58&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;8&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;   access&lt;font color="#990000"&gt;:&lt;/font&gt; access&lt;font color="#990000"&gt;,&lt;/font&gt;
90b65208 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;11&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;58&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;9&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;   secret&lt;font color="#990000"&gt;:&lt;/font&gt; secret
205db396 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;03&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;59&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt; &lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; }&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#990000"&gt;...&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Every line gets annotated with the commit who introduced it and by whom.
Very helpful.&lt;/p&gt;

&lt;h2&gt;Who deleted that line?&lt;/h2&gt;

&lt;p&gt;Another feature, which is not as well known, is &lt;code&gt;git blame --reverse&lt;/code&gt;.
It allows you to see the file as it was before, annotated to show you
where it has been changed.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Check the what lines have been changed since the last 6 commits.&lt;/font&gt;&lt;/i&gt;
$ git blame --reverse head&lt;font color="#990000"&gt;~&lt;/font&gt;&lt;font color="#993399"&gt;6&lt;/font&gt;&lt;font color="#990000"&gt;..&lt;/font&gt;head security-test&lt;font color="#990000"&gt;.&lt;/font&gt;js
558b8e7f &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;53&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var vows &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'vows'&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt;
558b8e7f &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;53&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;     assert &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'assert'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
558b8e7f &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;53&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
093c13e9 &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;24&lt;/font&gt; &lt;font color="#993399"&gt;17&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;26&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;09&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var Security &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'dynamo-db'&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;Security&lt;font color="#990000"&gt;;&lt;/font&gt;
ba6c4d8b &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;09&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;46&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;5&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
&lt;font color="#990000"&gt;^&lt;/font&gt;b96c68b &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;12&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;33&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;50&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;6&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var access &lt;font color="#990000"&gt;=&lt;/font&gt; process&lt;font color="#990000"&gt;.&lt;/font&gt;env&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;'S3_KEY'&lt;/font&gt;&lt;font color="#990000"&gt;];&lt;/font&gt;
&lt;font color="#990000"&gt;^&lt;/font&gt;b96c68b &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;12&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;33&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;50&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;7&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var secret &lt;font color="#990000"&gt;=&lt;/font&gt; process&lt;font color="#990000"&gt;.&lt;/font&gt;env&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;'S3_SECRET'&lt;/font&gt;&lt;font color="#990000"&gt;];&lt;/font&gt;
558b8e7f &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;53&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;8&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
558b8e7f &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;53&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;  &lt;font color="#993399"&gt;9&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; var security &lt;font color="#990000"&gt;=&lt;/font&gt; new Security&lt;font color="#990000"&gt;(&lt;/font&gt;{
558b8e7f &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;53&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt; &lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;   access&lt;font color="#990000"&gt;:&lt;/font&gt; access&lt;font color="#990000"&gt;,&lt;/font&gt;
558b8e7f &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;53&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt; &lt;font color="#993399"&gt;11&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;   secret&lt;font color="#990000"&gt;:&lt;/font&gt; secret
558b8e7f &lt;font color="#990000"&gt;(&lt;/font&gt;Anders Janmyr &lt;font color="#993399"&gt;2012&lt;/font&gt;-&lt;font color="#993399"&gt;01&lt;/font&gt;-&lt;font color="#993399"&gt;25&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;53&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;52&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt; &lt;font color="#993399"&gt;12&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; }&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;In the output you can see that most of the lines are still the same at
HEAD (558b8e7f). But the fourth and fifth line &lt;code&gt;093c13e9&lt;/code&gt; and &lt;code&gt;ba6c4d8b&lt;/code&gt;
don&amp;#39;t exist anymore. And the sixth and seventh lines &lt;code&gt;^b96c68b&lt;/code&gt; have
been changed after this commit.&lt;/p&gt;

&lt;h2&gt;What commits contain the string?&lt;/h2&gt;

&lt;p&gt;Another thing I find very useful is to find out when certain words or
sentences are removed or added. For this you can use &lt;code&gt;git log -S&amp;lt;string&amp;gt;&lt;/code&gt; or
&lt;code&gt;git log -G&amp;lt;regex&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Find commits that modified the string aws and display the full diff.&lt;/font&gt;&lt;/i&gt;
$ git log -Saws --diff-filter&lt;font color="#990000"&gt;=&lt;/font&gt;M --patch
commit b96c68b839f204b310b79570bc3d27dc93cff588
Author&lt;font color="#990000"&gt;:&lt;/font&gt; Anders Janmyr &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;anders@janmyr&lt;font color="#990000"&gt;.&lt;/font&gt;com&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt;
Date&lt;font color="#990000"&gt;:&lt;/font&gt;   Sat Jan &lt;font color="#993399"&gt;21&lt;/font&gt; &lt;font color="#993399"&gt;12&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;33&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;50&lt;/font&gt; &lt;font color="#993399"&gt;2012&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;0100&lt;/font&gt;

    We have a valid request&lt;font color="#990000"&gt;,&lt;/font&gt; tjohoo

diff --git a/lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js b/lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js
index bee6936&lt;font color="#990000"&gt;..&lt;/font&gt;&lt;font color="#993399"&gt;8471527&lt;/font&gt; &lt;font color="#993399"&gt;100644&lt;/font&gt;
--- a/lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js
&lt;font color="#990000"&gt;+++&lt;/font&gt; b/lib/dynamo-db/security&lt;font color="#990000"&gt;.&lt;/font&gt;js
@@ -&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#993399"&gt;6&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#993399"&gt;7&lt;/font&gt; @@
 var crypto &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'crypto'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
 var _ &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'underscore'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
 var request &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"request"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#990000"&gt;+&lt;/font&gt;var xml2js &lt;font color="#990000"&gt;=&lt;/font&gt; require&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'xml2js'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
 
 &lt;b&gt;&lt;font color="#000000"&gt;function Security&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;options&lt;font color="#990000"&gt;)&lt;/font&gt; {
   this&lt;font color="#990000"&gt;.&lt;/font&gt;options &lt;font color="#990000"&gt;=&lt;/font&gt; options&lt;font color="#990000"&gt;;&lt;/font&gt;
@@ -&lt;font color="#993399"&gt;23&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#993399"&gt;7&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;24&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#993399"&gt;7&lt;/font&gt; @@ mod&lt;font color="#990000"&gt;.&lt;/font&gt;timestamp &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;function()&lt;/font&gt;&lt;/b&gt; {
 mod&lt;font color="#990000"&gt;.&lt;/font&gt;defaultParams &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;function()&lt;/font&gt;&lt;/b&gt; {
   &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; {
     AWSAccessKeyId&lt;font color="#990000"&gt;:&lt;/font&gt; this&lt;font color="#990000"&gt;.&lt;/font&gt;options&lt;font color="#990000"&gt;.&lt;/font&gt;access&lt;font color="#990000"&gt;,&lt;/font&gt;
-    Version&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;'2010-05-08'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
&lt;font color="#990000"&gt;+&lt;/font&gt;    Version&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;'2011-06-15'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
     Timestamp&lt;font color="#990000"&gt;:&lt;/font&gt; this&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;timestamp()&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
     SignatureVersion&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
     SignatureMethod&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;'HmacSHA256'&lt;/font&gt;
@@ -&lt;font color="#993399"&gt;57&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#993399"&gt;9&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;font color="#993399"&gt;58&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt; @@ mod&lt;font color="#990000"&gt;.&lt;/font&gt;url &lt;font color="#990000"&gt;=&lt;/font&gt; function&lt;font color="#990000"&gt;(&lt;/font&gt;host&lt;font color="#990000"&gt;,&lt;/font&gt; path&lt;font color="#990000"&gt;,&lt;/font&gt; params&lt;font color="#990000"&gt;)&lt;/font&gt; {
 
 mod&lt;font color="#990000"&gt;.&lt;/font&gt;makeRequest &lt;font color="#990000"&gt;=&lt;/font&gt; function&lt;font color="#990000"&gt;(&lt;/font&gt;method&lt;font color="#990000"&gt;,&lt;/font&gt; host&lt;font color="#990000"&gt;,&lt;/font&gt; path&lt;font color="#990000"&gt;,&lt;/font&gt; params&lt;font color="#990000"&gt;,&lt;/font&gt; callback&lt;font color="#990000"&gt;)&lt;/font&gt; {
   var extParams &lt;font color="#990000"&gt;=&lt;/font&gt; _&lt;font color="#990000"&gt;.&lt;/font&gt;extend&lt;font color="#990000"&gt;(&lt;/font&gt;{}&lt;font color="#990000"&gt;,&lt;/font&gt; this&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;defaultParams()&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; params&lt;font color="#990000"&gt;);&lt;/font&gt;
-  var signedParams &lt;font color="#990000"&gt;=&lt;/font&gt; this&lt;font color="#990000"&gt;.&lt;/font&gt;signedParams&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'GET'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'iam.amazonaws.com'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'/'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; extParams&lt;font color="#990000"&gt;);&lt;/font&gt;
-  console&lt;font color="#990000"&gt;.&lt;/font&gt;log&lt;font color="#990000"&gt;(&lt;/font&gt;extParams&lt;font color="#990000"&gt;,&lt;/font&gt;signedParams&lt;font color="#990000"&gt;);&lt;/font&gt;
-  &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; request&lt;font color="#990000"&gt;(&lt;/font&gt;{ method&lt;font color="#990000"&gt;:&lt;/font&gt; method&lt;font color="#990000"&gt;,&lt;/font&gt; url&lt;font color="#990000"&gt;:&lt;/font&gt; this&lt;font color="#990000"&gt;.&lt;/font&gt;url&lt;font color="#990000"&gt;(&lt;/font&gt;host&lt;font color="#990000"&gt;,&lt;/font&gt; path&lt;font color="#990000"&gt;,&lt;/font&gt; signedParams&lt;font color="#990000"&gt;)&lt;/font&gt; }&lt;font color="#990000"&gt;,&lt;/font&gt;
&lt;font color="#990000"&gt;+&lt;/font&gt;  var signedParams &lt;font color="#990000"&gt;=&lt;/font&gt; this&lt;font color="#990000"&gt;.&lt;/font&gt;signedParams&lt;font color="#990000"&gt;(&lt;/font&gt;method&lt;font color="#990000"&gt;,&lt;/font&gt; host&lt;font color="#990000"&gt;,&lt;/font&gt; path&lt;font color="#990000"&gt;,&lt;/font&gt; extParams&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#990000"&gt;+&lt;/font&gt;  var url &lt;font color="#990000"&gt;=&lt;/font&gt; this&lt;font color="#990000"&gt;.&lt;/font&gt;url&lt;font color="#990000"&gt;(&lt;/font&gt;host&lt;font color="#990000"&gt;,&lt;/font&gt; path&lt;font color="#990000"&gt;,&lt;/font&gt; signedParams&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#990000"&gt;+&lt;/font&gt;  console&lt;font color="#990000"&gt;.&lt;/font&gt;log&lt;font color="#990000"&gt;(&lt;/font&gt;url&lt;font color="#990000"&gt;,&lt;/font&gt;signedParams&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#990000"&gt;+&lt;/font&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; request&lt;font color="#990000"&gt;(&lt;/font&gt;{ method&lt;font color="#990000"&gt;:&lt;/font&gt; method&lt;font color="#990000"&gt;,&lt;/font&gt; url&lt;font color="#990000"&gt;:&lt;/font&gt; url }&lt;font color="#990000"&gt;,&lt;/font&gt;
&lt;font color="#990000"&gt;...&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;That&amp;#39;s all folks!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-7807098460042512358?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/7807098460042512358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=7807098460042512358' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7807098460042512358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7807098460042512358'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2012/01/finding-with-git.html' title='Finding with Git'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-2860510570053284651</id><published>2011-10-04T17:37:00.002+02:00</published><updated>2011-10-04T17:40:03.320+02:00</updated><title type='text'>7 Reasons to go to Øredev 2011</title><content type='html'>
&lt;p&gt;
I&amp;rsquo;m am looking forward to &amp;Oslash;redev 2011 more than I have looked forward to
any of the previous ones. The reason for this is that &amp;Oslash;redev has finally
become a leading conference for dynamic programming.&lt;/p&gt;

&lt;p&gt;
&amp;Oslash;redev has always been good in the enterprise sphere led by Java, .Net and
mobile tracks, but it has been weaker in the area of dynamic programming
languages. Last year was better than before, but this year is going
to be great. Here are some speakers that you should not miss.&lt;/p&gt;

&lt;h2&gt;
Yehuda Katz&lt;/h2&gt;

&lt;p&gt;
Yehuda Katz was one of the driving forces behind the great Rails
3 refactoring, that made sure that Rails will remain the most productive
web development environment for many years to come. Yehuda just released
a new book,
&lt;a href="http://www.amazon.com/Rails-3-Action-Yehuda-Katz/dp/1935182277?tag=thtasta-20"&gt;Rails 3 in Action&lt;/a&gt;, Its the first book about Rails 3.1, including the awesome
&lt;a href="http://guides.rubyonrails.org/asset_pipeline.html"&gt;Asset Pipeline&lt;/a&gt;,
&lt;a href="http://asciicasts.com/episodes/266-http-streaming"&gt;streaming&lt;/a&gt;,
and &lt;a href="http://guides.rubyonrails.org/migrations.html#writing-your-change-method"&gt;reversible migrations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;
Yehuda has also been involved with jQuery and written
&lt;a href="http://www.amazon.com/jQuery-Action-Second-Bear-Bibeault/dp/1935182323?tag=thtasta-20"&gt;jQuery in Action&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;
He will be speaking about &lt;a href="http://oredev.org/2011/sessions/rails"&gt;Rails&lt;/a&gt; and
&lt;a href="http://oredev.org/2011/sessions/sproutcore"&gt;Sproutcore&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
Felix Geisend&amp;ouml;rfer&lt;/h2&gt;

&lt;p&gt;
Felix Geisend&amp;ouml;rfer is a core Node.js developer and he will of course be
talking about
&lt;a href="http://oredev.org/2011/sessions/node-js--a-practical-introduction"&gt;Node&lt;/a&gt;.
Node.js is a set of Javascript libraries that runs on top of the Google
V8 virtual machine. What is interesting about Node, apart from being
server-side Javascript is that it uses asynchronous programming as the
default. This default makes Node extremely interesting for developing
solutions involving multiple open connections, such as websockets, and
for streaming video and audio.  Node is definitely part of the future of
the web. I have written
&lt;a href="http://anders.janmyr.com/2011/05/not-very-short-introduction-to-nodejs.html"&gt;extensively about it&lt;/a&gt; in the past.&lt;/p&gt;

&lt;h2&gt;
Corey Haines&lt;/h2&gt;

&lt;p&gt;
Cory Haines is a legend in the TDD community. He is also famous for his
&lt;a href="http://coderetreat.com/"&gt;Code Retreats&lt;/a&gt;. He will give one workshop, 
&lt;a href="http://oredev.org/2011/sessions/improving-your-tdd"&gt;Improving your TDD&lt;/a&gt;, and
two presentations, 
&lt;a href="http://oredev.org/2011/sessions/fast-ruby-on-rails-tests"&gt;Fast Ruby on Rails Tests&lt;/a&gt; and
&lt;a href="http://oredev.org/2011/sessions/come-introduce-yourself-to-the-concepts-and-fundamental-technique-behind-tdd"&gt;Come introduce yourself to the concepts and fundamental technique behind TDD&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
Ilya Grigorik&lt;/h2&gt;

&lt;p&gt;
Ilya Grigorik is the founder of &lt;a href="http://www.postrank.com/"&gt;PostRank&lt;/a&gt;,
that was recently acquired by Google. He is now working on Social
Analytics at Google. At PostRank he used Ruby to perform analysis on
very large amounts of data. While doing this he developed
&lt;a href="http://postrank-labs.github.com/goliath/"&gt;Goliath&lt;/a&gt;,
a high-performance non-blocking web server using Ruby 1.9 and fibers.
He will be talking about
&lt;a href="http://oredev.org/2011/sessions/0-60-with-goliath-building-high-performance-ruby-web-services"&gt;Goliath&lt;/a&gt;,
&lt;a href="http://oredev.org/2011/sessions/modeling-concurrency-in-ruby-and-beyond"&gt;Concurrency&lt;/a&gt; and
&lt;a href="http://oredev.org/2011/sessions/intelligent-code-getting-started-with-machine-learning"&gt;Machine Learning&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
I can recommend that you
&lt;a href="https://twitter.com/#!/igrigorik"&gt;follow Ilya on Twitter&lt;/a&gt;
since his tweets has the highest signal-to-noise ratio I know of.&lt;/p&gt;

&lt;p&gt;
And, finally, make sure to check out &lt;a href="http://vimgolf.com/"&gt;Vim Golf&lt;/a&gt;,
a really cool way to become a Vim wizard.&lt;/p&gt;

&lt;h2&gt;
Trevor Burnham&lt;/h2&gt;

&lt;p&gt;
&lt;a href="http://jashkenas.github.com/coffee-script/"&gt;Coffeescript&lt;/a&gt; is the new
way to write Javascript without actually writing it :). Coffeescript is
an elegant language, created by Jeremy Ashkenas, with features from Ruby
and Python. The language is very pure and removes a lot of clutter.
Coffeescript is compiled into good, efficient Javascript. Trevor Burnham 
has written a book,
&lt;a href="http://www.amazon.com/CoffeeScript-Accelerated-JavaScript-Development-Pragmatic/dp/1934356786?tag=thtasta-20"&gt;CoffeeScript: Accelerated JavaScript Development&lt;/a&gt;, on the
subject and he will be giving two presentations about it,
&lt;a href="http://oredev.org/2011/sessions/coffeescript-design-patterns-for-the-new-javascript"&gt;CoffeeScript: Design Patterns for the New JavaScript&lt;/a&gt;
and
&lt;a href="http://oredev.org/2011/sessions/transforming-data-into-pixels-visualization-with-canvas-and-coffeescript"&gt;Transforming Data into Pixels: Visualization with Canvas and CoffeeScript&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
Charles Nutter&lt;/h2&gt;

&lt;p&gt;
Charles Nutter is the man behind JRuby. He has also create another
language called &lt;a href=""&gt;Mirah&lt;/a&gt;, which he will be talking about in
&lt;a href="http://oredev.org/2011/sessions/have-you-tried-mirah-yet"&gt;Have you tried Mirah yet?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;
While doing all this he has obviously learned a thing or two about the
JVM and about bytecodes. Who could be better to teach us about the
internals of the JVM. Charles will be giving another talk about this in
&lt;a href="http://oredev.org/2011/sessions/what-the-jvm-does-with-your-bytecode-when-nobodys-looking"&gt;What the JVM Does With your Bytecode when Nobody&amp;rsquo;s Looking&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
Simon Peyton Jones&lt;/h2&gt;

&lt;p&gt;
Even though this list of people is mostly about dynamic programming
languages, it has to include
&lt;a href="http://oredev.org/2011/speakers/simon-peyton-jones"&gt;Simon Peyton Jones&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;
Haskell is one of the most statically typed languages there is. It
is, probably, also the most elegant programming language in the world.
It is purely functional, has lazy evaluation, pattern matching, and
currying by default. Even if you never use Haskell in a real-life
project learning Haskell will be worth your while. If you want to get
a good introduction to Haskell I can highly recommend
&lt;a href="http://www.amazon.com/Programming-Haskell-Graham-Hutton/dp/0521871727?tag=thtasta-20"&gt;Programming in Haskell&lt;/a&gt; by Graham Hutton.&lt;/p&gt;

&lt;h2&gt;
Summary&lt;/h2&gt;

&lt;p&gt;
As you can see, &lt;a href="http://oredev.org/2011/"&gt;this years &amp;Oslash;redev&lt;/a&gt; is looking
better than ever before and I have only included a select part of it in
this post. Missing it should be considered professional misconduct!&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-2860510570053284651?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/2860510570053284651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=2860510570053284651' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2860510570053284651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2860510570053284651'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/10/7-reasons-to-go-to-2011.html' title='7 Reasons to go to &amp;Oslash;redev 2011'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-158474083671484629</id><published>2011-08-09T14:17:00.004+02:00</published><updated>2011-08-09T14:35:27.699+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='coffeescript'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>jQuery Changes From 1.4.2 to 1.6</title><content type='html'>&lt;p&gt;jQuery is a powerful library and it is possible to get by without
using any of the new features. That&amp;rsquo;s why many of us
just upgrade to a new version assuming that it is mostly bug and
performance fixes. This is not the case. jQuery 1.4.2 was released in
February 2010 and it&amp;rsquo;s been one and a half years and a number of
releases since then.&lt;/p&gt; 
 
&lt;p&gt;I was going to write about the changes in 1.5 and 1.6, but I have
noticed that many people have missed some of the new features of the 1.4
releases. And by the way, all examples are written in Coffeescript.&lt;/p&gt; 
 
&lt;h2&gt;Selected changes from 1.4.2+&lt;/h2&gt; 
 
&lt;h3&gt;&lt;code&gt;delegate()&lt;/code&gt;&lt;/h3&gt; 
 
&lt;p&gt;Most people know about &lt;code&gt;live()&lt;/code&gt; and how it can be used to attach
listeners to elements that don&amp;rsquo;t yet exist in the DOM. &lt;code&gt;live()&lt;/code&gt; has
a younger brother that was born in 1.4.2 and he is called &lt;code&gt;delegate()&lt;/code&gt;.
&lt;code&gt;delegate()&lt;/code&gt; is more powerful. It gives you more precision in
where to attach the listener.  &lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'.main-content'&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;find&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'section'&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;delegate &lt;font color="#FF0000"&gt;'p'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'click'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 
  $&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;addClass &lt;font color="#FF0000"&gt;'highlight'&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;As you can see above, &lt;code&gt;delegate()&lt;/code&gt;, unlike &lt;code&gt;live()&lt;/code&gt;, can be chained like
normal jQuery calls.&lt;/p&gt; 
 
&lt;h3&gt;&lt;code&gt;jQuery.now()&lt;/code&gt;, &lt;code&gt;jQuery.type()&lt;/code&gt; and &lt;code&gt;jQuery.parseXML()&lt;/code&gt;&lt;/h3&gt; 
 
&lt;p&gt;Nothing special here, just some utilities that are good to know about.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;now&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;is&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Date&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;getTime&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; 
 
$&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;type&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'hello'&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; is &lt;font color="#FF0000"&gt;'string'&lt;/font&gt; 
 
xml &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;"""&lt;/font&gt; 
&lt;font color="#FF0000"&gt;&amp;lt;rss version='2.0'&amp;gt;&lt;/font&gt; 
&lt;font color="#FF0000"&gt;&amp;lt;channel&amp;gt;&lt;/font&gt; 
&lt;font color="#FF0000"&gt;&amp;lt;title&amp;gt;RSS Title&amp;lt;/title&amp;gt;&lt;/font&gt; 
&lt;font color="#FF0000"&gt;&amp;lt;/channel&amp;gt;&lt;/font&gt; 
&lt;font color="#FF0000"&gt;&amp;lt;/rss&amp;gt;&lt;/font&gt; 
&lt;font color="#FF0000"&gt;"""&lt;/font&gt; 
xmlDoc &lt;font color="#990000"&gt;=&lt;/font&gt; $&lt;font color="#990000"&gt;.&lt;/font&gt;parseXML xml 
&lt;font color="#990000"&gt;(&lt;/font&gt;$&lt;font color="#990000"&gt;(&lt;/font&gt;xmlDoc&lt;font color="#990000"&gt;).&lt;/font&gt;find &lt;font color="#FF0000"&gt;'title'&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;text&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; is &lt;font color="#FF0000"&gt;'RSS Title'&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;All these utilities are interesting, but the truly good thing that came
out of jQuery-1.5+ is &lt;code&gt;Deferred()&lt;/code&gt;.&lt;/p&gt; 
 
&lt;h3&gt;&lt;code&gt;Deferred()&lt;/code&gt;&lt;/h3&gt; 
 
&lt;p&gt;With the release of jQuery 1.5 the internal implementation of &lt;code&gt;$.ajax&lt;/code&gt; 
was changed to use &lt;code&gt;Deferred()&lt;/code&gt;, and, even better, the implementation
was deemed so useful, that it became part of the public API.&lt;/p&gt; 
 
&lt;p&gt;Here is how you can use it via the &lt;code&gt;$.ajax&lt;/code&gt; method.&lt;/p&gt; 
 
&lt;p&gt;Declare a function hex that calls the &lt;code&gt;/hex&lt;/code&gt; url on the server, which
will return a hex value between &lt;strong&gt;00&lt;/strong&gt; and &lt;strong&gt;FF&lt;/strong&gt;.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;  hex &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 
    $&lt;font color="#990000"&gt;.&lt;/font&gt;ajax &lt;font color="#FF0000"&gt;{&lt;/font&gt; url&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;'/hex'&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Call the function multiple times, and you get a new &lt;code&gt;Deferred&lt;/code&gt; back for
each call. Notice the lack of handlers for the calls.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;  red &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;hex&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; 
  green &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;hex&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; 
  blue &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;hex&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Attach handlers to each of the &lt;code&gt;Deferred&lt;/code&gt;s to do something useful with
the returned value. Notice the use of &lt;code&gt;done&lt;/code&gt; instead of &lt;code&gt;success&lt;/code&gt;.
&lt;code&gt;success&lt;/code&gt; is deprecated and will be removed in 1.8.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;  red&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;done&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;hh&lt;font color="#990000"&gt;)-&amp;gt;&lt;/font&gt; 
    $&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"#r"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;css &lt;font color="#FF0000"&gt;'background-color'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"##{hh}0000"&lt;/font&gt; 
  green&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;done&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;hh&lt;font color="#990000"&gt;)-&amp;gt;&lt;/font&gt; 
    $&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"#g"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;css &lt;font color="#FF0000"&gt;'background-color'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"#00#{hh}00"&lt;/font&gt; 
  blue&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;done&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;hh&lt;font color="#990000"&gt;)-&amp;gt;&lt;/font&gt; 
    $&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"#b"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;css &lt;font color="#FF0000"&gt;'background-color'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"#0000#{hh}"&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;I am not limited to adding one handler, I can attach as many as I like.
Here I attach another one for logging the success of the &lt;code&gt;red&lt;/code&gt;-call.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;  red&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;done&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;hh&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 
    console&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;log&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;hh&lt;font color="#990000"&gt;)&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;If this was all there was to it, I would be happy, but it is not by
using the &lt;code&gt;$.when&lt;/code&gt; method I get a new &lt;code&gt;Deferred&lt;/code&gt; object that orchestrates
multiple &lt;code&gt;Deferred&lt;/code&gt;s in a very simple way. Let me create a color-&lt;code&gt;Deferred&lt;/code&gt; 
that waits for the others to return and then calls a new callback when
they are all done.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;  color &lt;font color="#990000"&gt;=&lt;/font&gt; $&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;when&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;red&lt;font color="#990000"&gt;,&lt;/font&gt; green&lt;font color="#990000"&gt;,&lt;/font&gt; blue&lt;font color="#990000"&gt;)&lt;/font&gt; 
 
  color&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;done&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;r&lt;font color="#990000"&gt;,&lt;/font&gt; g&lt;font color="#990000"&gt;,&lt;/font&gt; b&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 
    $&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"#color"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;css &lt;font color="#FF0000"&gt;'background-color'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"##{r[0]}#{g[0]}#{b[0]}"&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;The results from the requests are given in the same order as the
&lt;code&gt;Deferred&lt;/code&gt; objects are passed in. The results are given as an array with
three arguments &lt;code&gt;[ data, &amp;lsquo;success&amp;rsquo; , deferred ]&lt;/code&gt;.&lt;/p&gt; 
 
&lt;p&gt;You can see the example, a simple Sinatra app, in action on
&lt;a href="http://colors-deferred.herokuapp.com/"&gt;Heroku&lt;/a&gt; 
and the source code can be found on
&lt;a href="https://github.com/andersjanmyr/colors"&gt;Github&lt;/a&gt;&lt;/p&gt; 
 
&lt;p&gt;Very nice! Apart from the examples I have shown, there are methods
working with &lt;code&gt;Deferred&lt;/code&gt;. Methods for creating, &lt;code&gt;jQuery.Deferred()&lt;/code&gt;,
resolving, &lt;code&gt;resolve(), resolveWith()&lt;/code&gt;, and rejecting, &lt;code&gt;reject(),
rejectWith()&lt;/code&gt;.&lt;/p&gt; 
 
&lt;p&gt;To attach handlers to the events, you can use &lt;code&gt;done()&lt;/code&gt; for resolve,
&lt;code&gt;fail&lt;/code&gt; for reject, &lt;code&gt;always()&lt;/code&gt; for both resolve and reject. You can also
use &lt;code&gt;then(doneCallback, failCallback)&lt;/code&gt; to attach both a &lt;code&gt;done&lt;/code&gt; and a
&lt;code&gt;fail&lt;/code&gt; handler with one call.&lt;/p&gt; 
 
&lt;p&gt;&lt;code&gt;Deferred&lt;/code&gt;s are really cool, check them out
&lt;a href="http://api.jquery.com/category/deferred-object/"&gt;here&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-158474083671484629?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/158474083671484629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=158474083671484629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/158474083671484629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/158474083671484629'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/08/jquery-changes-from-142-to-16.html' title='jQuery Changes From 1.4.2 to 1.6'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-2791142526394209971</id><published>2011-06-05T15:49:00.003+02:00</published><updated>2011-06-05T15:52:37.490+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><title type='text'>Tips from Rails Anti-Patterns</title><content type='html'>&lt;p&gt;Another good Ruby book is out,
&lt;a href="http://www.amazon.com/Rails-AntiPatterns-Refactoring-Addison-Wesley-Professional/dp/0321604814"&gt;Rails Anti-Patterns&lt;/a&gt;.
The book is loaded with good tips on everything from following the &lt;em&gt;Law
of Demeter&lt;/em&gt; to cleaning up your views with the use of helper methods.&lt;/p&gt;

&lt;p&gt;Here are some things I picked up from the book.&lt;/p&gt;

&lt;h2&gt;&lt;code&gt;delegate&lt;/code&gt; can take a &lt;code&gt;:prefix&lt;/code&gt; argument&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;delegate&lt;/code&gt; method from &lt;code&gt;active_support&lt;/code&gt; is used for delegating calls
to another object without having to write out the full delegating
methods. It can take a prefix option to customize the name of the
delegating methods.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Address
  &lt;font color="#009900"&gt;@attr_accessors&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;street&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;zip
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Person
  attr_reader &lt;font color="#990000"&gt;:&lt;/font&gt;address
  &lt;i&gt;&lt;font color="#9A1900"&gt;# prefix =&amp;gt; true, results in the model name being used as prefix&lt;/font&gt;&lt;/i&gt;
  delegate &lt;font color="#990000"&gt;:&lt;/font&gt;street&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;zip&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;to &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;address&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;prefix &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;true&lt;/font&gt;&lt;/b&gt;
  &lt;i&gt;&lt;font color="#9A1900"&gt;#@person.address_street, @person.address_zip&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Person
  attr_reader &lt;font color="#990000"&gt;:&lt;/font&gt;billing_address&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;delivery_address
  &lt;i&gt;&lt;font color="#9A1900"&gt;# prefix =&amp;gt; string, uses the string as prefix&lt;/font&gt;&lt;/i&gt;
  delegate &lt;font color="#990000"&gt;:&lt;/font&gt;street&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;zip&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;to &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;address&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;prefix &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; delivery
  &lt;i&gt;&lt;font color="#9A1900"&gt;#@person.delivery_street, @person.delivery_zip&lt;/font&gt;&lt;/i&gt;
  delegate &lt;font color="#990000"&gt;:&lt;/font&gt;street&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;zip&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;to &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;address&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;prefix &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; billing
  &lt;i&gt;&lt;font color="#9A1900"&gt;#@person.billing_street, @person.billing_zip&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Transaction Scope&lt;/h2&gt;

&lt;p&gt;The code executed in the ActiveRecord callbacks execute in the same
transaction as the actual call to save, create, update, or delete.
Knowing this helps to eliminate unneccessary explicit transactions.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Using a before filter&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Drink
  before_create &lt;font color="#990000"&gt;:&lt;/font&gt;remove_ingredients_from_bar

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; remove_ingredients
    ingredients&lt;font color="#990000"&gt;.&lt;/font&gt;each &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;ingredient&lt;font color="#990000"&gt;|&lt;/font&gt;
      Bar&lt;font color="#990000"&gt;.&lt;/font&gt;remove&lt;font color="#990000"&gt;(&lt;/font&gt;ingredient&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Is better than using an explicit transaction&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Drink
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; create_drink
    transaction &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
      remove_ingredients
      create
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; remove_ingredients
    ingredients&lt;font color="#990000"&gt;.&lt;/font&gt;each &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;ingredient&lt;font color="#990000"&gt;|&lt;/font&gt;
      Bar&lt;font color="#990000"&gt;.&lt;/font&gt;remove&lt;font color="#990000"&gt;(&lt;/font&gt;ingredient&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Association Methods&lt;/h2&gt;

&lt;p&gt;It is possible to add methods directly on the activerecord associations.
This is especially handy if the method uses information from both sides
of the relation.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Drink
  &lt;i&gt;&lt;font color="#9A1900"&gt;#has_field :minimum_drinking_age&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Customer
  &lt;i&gt;&lt;font color="#9A1900"&gt;#has_field :age&lt;/font&gt;&lt;/i&gt;

  has_many &lt;font color="#990000"&gt;:&lt;/font&gt;drinks &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; allowed
      &lt;i&gt;&lt;font color="#9A1900"&gt;# proxy_owner is the object defining the relation, Customer&lt;/font&gt;&lt;/i&gt;
      where&lt;font color="#990000"&gt;([&lt;/font&gt;&lt;font color="#FF0000"&gt;'minimum_drinking_age &amp;lt; ?'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; proxy_owner&lt;font color="#990000"&gt;.&lt;/font&gt;age&lt;font color="#990000"&gt;])&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;When to make a model active&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;If there is no user interface for adding, removing, or managing data,
there is no need for an active model. A denormalized column populated
by a hash or array of possible values is fine. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is really just the application of the KISS principle, Keep It
Simple Stupid, but I have never seen it as clearly described before
reading this book.&lt;/p&gt;

&lt;h2&gt;Haml []&lt;/h2&gt;

&lt;p&gt;A nice feature of Haml that I didn&amp;rsquo;t know about, is the [] operator.
When given an object, such as [record], [] acts as a combination of
&lt;code&gt;div_for&lt;/code&gt; and &lt;code&gt;content_for&lt;/code&gt;, outputting a tag with the id and class
attributes set appropriately.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;font color="#990000"&gt;-&lt;/font&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# This Haml&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;%&lt;/font&gt;span&lt;font color="#990000"&gt;[&lt;/font&gt;@team&lt;font color="#990000"&gt;]&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;&amp;lt;!-- Results in this HTML --&amp;gt;&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;span&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;'team'&lt;/font&gt; &lt;font color="#009900"&gt;id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;'team_1'&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;RESTful actions&lt;/h2&gt;

&lt;p&gt;When using resources in Rails there are seven methods that are used.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index, create, show, update, delete, edit&lt;/code&gt;, and &lt;code&gt;new&lt;/code&gt;. The first five
naturally map to &lt;code&gt;get(collection), post(collection), get(singular), 
put(singular)&lt;/code&gt;, and &lt;code&gt;delete(singular)&lt;/code&gt;, but what isn&amp;rsquo;t as obvious is
that.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The new and edit actions are really just different ways of representing
the show action.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is of course obvious when you think about it, but once again Chad
and Tammer has written it down in plain simple English.&lt;/p&gt;

&lt;h2&gt;Rake Tasks&lt;/h2&gt;

&lt;p&gt;How should you treat your application specific Rake tasks on order to
test them easily. Once again the solution is very simple.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Write the domain specific code as a class method on the appropriate
model associated with the task.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then all you have to do is call the method from the task.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;task &lt;font color="#990000"&gt;:&lt;/font&gt;fill_bar_with_ingredients &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
  Bar&lt;font color="#990000"&gt;.&lt;/font&gt;fill_with_ingredients
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;It is not always appropriate to add this functionality to the existing
models. This is a clue that another model is needed in your domain.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;task &lt;font color="#990000"&gt;:&lt;/font&gt;fill_bar_with_ingredients &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
  LiquorStore&lt;font color="#990000"&gt;.&lt;/font&gt;order_ingredients
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Database Index&lt;/h2&gt;

&lt;p&gt;Since most applications have far more reads than writes, you should add
indexes to every field that appears in a &lt;code&gt;WHERE&lt;/code&gt; clause or an &lt;code&gt;ORDER&lt;/code&gt;
clause. You should also add indexes for every combination of fields that
are used that are combined with &lt;code&gt;AND&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As always, don&amp;rsquo;t follow this advice blindely, if a table only has three
rows then perhaps the index is overkill&amp;hellip;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Apart from these tips, there are tons of other useful information,
making this book a must-read if you are doing Rails development.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-2791142526394209971?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/2791142526394209971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=2791142526394209971' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2791142526394209971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2791142526394209971'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/06/tips-from-rails-anti-patterns.html' title='Tips from Rails Anti-Patterns'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-7744918320648162029</id><published>2011-05-25T11:35:00.001+02:00</published><updated>2011-05-25T11:36:47.641+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='exceptions'/><title type='text'>Ruby, an Exceptional Language</title><content type='html'>&lt;p&gt;Based on the book &lt;a href="http://exceptionalruby.com/"&gt;Exceptional Ruby&lt;/a&gt; by
Avdi Grimm, I have developed a strategy for how I should deal with
exceptions in Ruby. &lt;/p&gt; 
 
&lt;p&gt;Being a very dynamic language, Ruby allows very flexible coding
techniques.  Exceptions are not an exception :).&lt;/p&gt; 
 
&lt;p&gt;When I am developing a library in Ruby I typically create one &lt;code&gt;Error&lt;/code&gt; 
module and one &lt;code&gt;StdError&lt;/code&gt; class. The &lt;code&gt;Error&lt;/code&gt; module is a typical
&lt;em&gt;tag module&lt;/em&gt; and does not contain any methods.&lt;/p&gt; 
 
&lt;h2&gt;Tag Module&lt;/h2&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Tag module for the Tapir library&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;module&lt;/font&gt;&lt;/b&gt; Tapir
  &lt;b&gt;&lt;font color="#0000FF"&gt;module&lt;/font&gt;&lt;/b&gt; Error
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;The reason for the tag module is that I can use it to tag exceptions
occurring inside my library without having to wrap them in a nested
exception.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;module&lt;/font&gt;&lt;/b&gt; Tapir
  &lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Downloader
 
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;get url
      HTTP&lt;font color="#990000"&gt;.&lt;/font&gt;get url
    &lt;b&gt;&lt;font color="#0000FF"&gt;rescue&lt;/font&gt;&lt;/b&gt; StandardError &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; error   &lt;i&gt;&lt;font color="#9A1900"&gt;# Rescue the error&lt;/font&gt;&lt;/i&gt; 
      &lt;i&gt;&lt;font color="#9A1900"&gt;# Namespace the error by tagging it with ::Tapir::Error&lt;/font&gt;&lt;/i&gt; 
      error&lt;font color="#990000"&gt;.&lt;/font&gt;extend&lt;font color="#990000"&gt;(::&lt;/font&gt;Tapir&lt;font color="#990000"&gt;::&lt;/font&gt;Error&lt;font color="#990000"&gt;)&lt;/font&gt;  
      &lt;b&gt;&lt;font color="#0000FF"&gt;raise&lt;/font&gt;&lt;/b&gt;                         &lt;i&gt;&lt;font color="#9A1900"&gt;# And raise it again&lt;/font&gt;&lt;/i&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;# Client usage&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;begin&lt;/font&gt;&lt;/b&gt; 
  Tapir&lt;font color="#990000"&gt;::&lt;/font&gt;Downloader&lt;font color="#990000"&gt;.&lt;/font&gt;get &lt;font color="#FF0000"&gt;'http://non.existent.url/'&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;rescue&lt;/font&gt;&lt;/b&gt; Tapir&lt;font color="#990000"&gt;::&lt;/font&gt;Error &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; error
  puts &lt;font color="#FF0000"&gt;"Stupid tapir, gave me error #{error.message}"&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;This is beautiful. I am scoping an internal error as my own. Since Ruby
is dynamic there is no need to declare a new class that wraps all the
methods in the &lt;code&gt;StandarError&lt;/code&gt; I have access to them anyway. Duck typing
for the win!&lt;/p&gt; 
 
&lt;h2&gt;A Nested Exception Class&lt;/h2&gt; 
 
&lt;p&gt;In some cases the tag module is not enough. Perhaps the exception was
not created by another exception. In that case I need a real class since
it is not possible to raise modules. But while I am at it I usually make
the class a nested exception in order to simplify wrapping of other
exceptions if the need comes up. This is how I do that.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;module&lt;/font&gt;&lt;/b&gt; Tapir
  &lt;i&gt;&lt;font color="#9A1900"&gt;# I usually call the class `StdError` since it prevents the user of&lt;/font&gt;&lt;/i&gt; 
  &lt;i&gt;&lt;font color="#9A1900"&gt;# the library from rescuing the global `StandardError`.&lt;/font&gt;&lt;/i&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; StdError &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; StandardError 
    extend Error             &lt;i&gt;&lt;font color="#9A1900"&gt;# Extend the Error tag module&lt;/font&gt;&lt;/i&gt; 
    attr_reader &lt;font color="#990000"&gt;:&lt;/font&gt;original    &lt;i&gt;&lt;font color="#9A1900"&gt;# Add an accessor for the original, if one exists&lt;/font&gt;&lt;/i&gt; 
   
    &lt;i&gt;&lt;font color="#9A1900"&gt;# Create the error with a message and an original that defaults to&lt;/font&gt;&lt;/i&gt; 
    &lt;i&gt;&lt;font color="#9A1900"&gt;# the exception that is currently active, in this thread, if one exists&lt;/font&gt;&lt;/i&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; initialize&lt;font color="#990000"&gt;(&lt;/font&gt;msg&lt;font color="#990000"&gt;,&lt;/font&gt; original&lt;font color="#990000"&gt;=&lt;/font&gt;$&lt;font color="#990000"&gt;!)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;super&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;msg&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;font color="#009900"&gt;@original&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; original&lt;font color="#990000"&gt;;&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;# Client Usage&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;begin&lt;/font&gt;&lt;/b&gt; 
  Tapir&lt;font color="#990000"&gt;.&lt;/font&gt;do_something_that_fails
&lt;b&gt;&lt;font color="#0000FF"&gt;rescue&lt;/font&gt;&lt;/b&gt; Tapir&lt;font color="#990000"&gt;::&lt;/font&gt;Error &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; error      &lt;i&gt;&lt;font color="#9A1900"&gt;# rescue the tag module&lt;/font&gt;&lt;/i&gt; 
  puts &lt;font color="#FF0000"&gt;"Bad tapir #{error.message}, due to #{error.original.message}"&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;# or if I want to be more specific&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;begin&lt;/font&gt;&lt;/b&gt; 
  Tapir&lt;font color="#990000"&gt;.&lt;/font&gt;do_something_that_fails
&lt;b&gt;&lt;font color="#0000FF"&gt;rescue&lt;/font&gt;&lt;/b&gt; Tapir&lt;font color="#990000"&gt;::&lt;/font&gt;StdError &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; error   &lt;i&gt;&lt;font color="#9A1900"&gt;# rescue the specific error&lt;/font&gt;&lt;/i&gt; 
  puts &lt;font color="#FF0000"&gt;"Bad tapir #{error.message}, due to #{error.original.message}"&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Notice that I don&amp;rsquo;t have to wrap the exception explicitly, since
I default the Exception to the last error that is stored in &lt;code&gt;$!&lt;/code&gt;. &lt;/p&gt; 
 
&lt;p&gt;Now the only reason for me to want to create a &lt;code&gt;Tapir::StdError&lt;/code&gt; apart
from it being misuse of my library is if I want to add additional information
to the exception that already occurred. In that case I may also want to
extend the &lt;code&gt;Tapir::StdError&lt;/code&gt; and create an exception with additional
fields.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;module&lt;/font&gt;&lt;/b&gt; Tapir
  
  &lt;i&gt;&lt;font color="#9A1900"&gt;# Create a specific exception to add more information for the client&lt;/font&gt;&lt;/i&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; TooOldError &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; StdError
    attr_reader &lt;font color="#990000"&gt;:&lt;/font&gt;age&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;max_age
 
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; initialize&lt;font color="#990000"&gt;(&lt;/font&gt;msg&lt;font color="#990000"&gt;,&lt;/font&gt; original&lt;font color="#990000"&gt;=&lt;/font&gt;$&lt;font color="#990000"&gt;!,&lt;/font&gt; age&lt;font color="#990000"&gt;,&lt;/font&gt; max_age&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;super&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;msg&lt;font color="#990000"&gt;,&lt;/font&gt; original&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;font color="#009900"&gt;@age&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#009900"&gt;@max_age&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; age&lt;font color="#990000"&gt;,&lt;/font&gt; max_age
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;# Client usage&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;begin&lt;/font&gt;&lt;/b&gt; 
  tapir&lt;font color="#990000"&gt;.&lt;/font&gt;mate&lt;font color="#990000"&gt;(&lt;/font&gt;other_tapir&lt;font color="#990000"&gt;)&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;rescue&lt;/font&gt;&lt;/b&gt; TooOldError &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; error
  &lt;i&gt;&lt;font color="#9A1900"&gt;# Use the specific error properties&lt;/font&gt;&lt;/i&gt; 
  puts &lt;font color="#FF0000"&gt;"Hey, your are #{error.age}, that is too damn old!"&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h2&gt;Throw &amp;ndash; Catch&lt;/h2&gt; 
 
&lt;p&gt;Ruby also has an alternative to &lt;code&gt;raise&lt;/code&gt; and &lt;code&gt;rescue&lt;/code&gt; called &lt;code&gt;throw&lt;/code&gt; and
&lt;code&gt;catch&lt;/code&gt;.&lt;/p&gt; 
 
&lt;p&gt;They should not be used as an alternative to exceptions, instead they are
&lt;a href="http://en.wikipedia.org/wiki/Continuation#Kinds_of_continuations"&gt;escape continuations&lt;/a&gt; 
that should be used to escape from nested control structures across
method calls. Powerful! Here is an example from &lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt;&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Here is the throw&lt;/font&gt;&lt;/i&gt; 
 
   &lt;i&gt;&lt;font color="#9A1900"&gt;# Pass control to the next matching route.&lt;/font&gt;&lt;/i&gt; 
    &lt;i&gt;&lt;font color="#9A1900"&gt;# If there are no more matching routes, Sinatra will&lt;/font&gt;&lt;/i&gt; 
    &lt;i&gt;&lt;font color="#9A1900"&gt;# return a 404 response.&lt;/font&gt;&lt;/i&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; pass&lt;font color="#990000"&gt;(&amp;amp;&lt;/font&gt;block&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;pass&lt;font color="#990000"&gt;,&lt;/font&gt; block
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;# and here is where it is caught&lt;/font&gt;&lt;/i&gt; 
 
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; process_route&lt;font color="#990000"&gt;(&lt;/font&gt;pattern&lt;font color="#990000"&gt;,&lt;/font&gt; keys&lt;font color="#990000"&gt;,&lt;/font&gt; conditions&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;font color="#990000"&gt;...&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;catch&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(:&lt;/font&gt;pass&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; 
        conditions&lt;font color="#990000"&gt;.&lt;/font&gt;each &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;cond&lt;font color="#990000"&gt;|&lt;/font&gt; 
          &lt;b&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;pass &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; instance_eval&lt;font color="#990000"&gt;(&amp;amp;&lt;/font&gt;cond&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;false&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
        &lt;b&gt;&lt;font color="#0000FF"&gt;yield&lt;/font&gt;&lt;/b&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;# Allowing usage such as&lt;/font&gt;&lt;/i&gt; 
 
  get &lt;font color="#FF0000"&gt;'/guess/:who'&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; 
    pass &lt;b&gt;&lt;font color="#0000FF"&gt;unless&lt;/font&gt;&lt;/b&gt; params&lt;font color="#990000"&gt;[:&lt;/font&gt;who&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#FF0000"&gt;'Frank'&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;'You got me!'&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
  get &lt;font color="#FF0000"&gt;'/guess/*'&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; 
    &lt;font color="#FF0000"&gt;'You missed!'&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Lovely!&lt;/p&gt; 
 
&lt;h2&gt;Wrap up&lt;/h2&gt; 
 
&lt;p&gt;This is how I use exceptions in Ruby now, thanks to ideas from the book.
Other good ideas from the book are the three guarantees:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;&lt;em&gt;The weak guarantee&lt;/em&gt;, if an exception is raised, the object will be in
a consistent state.&lt;/li&gt; 
&lt;li&gt;&lt;em&gt;The strong guarantee&lt;/em&gt;, if an exception is raised, the object will be
left in its initial state.&lt;/li&gt; 
&lt;li&gt;&lt;em&gt;The nothrow guarantee&lt;/em&gt;, no exceptions will be raised by this method.&lt;/li&gt; 
&lt;/ul&gt; 
 
&lt;p&gt;And a nice way of categorizing exceptions based on three different
usages by the client. (My categories are not exactly the same as Avdis)&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;&lt;em&gt;User Error&lt;/em&gt;, the client has used the library wrong.&lt;/li&gt; 
&lt;li&gt;&lt;em&gt;Internal Error&lt;/em&gt;, something is wrong with the library. We are looking
into the problem&amp;hellip;&lt;/li&gt; 
&lt;li&gt;&lt;em&gt;Transient Error&lt;/em&gt;, something is now working right now, but the same
call may succeed in a while. It is a good idea to provide a period
after whick the call will probably succeed. 
the client to try again.&lt;/li&gt; 
&lt;/ul&gt; 
 
&lt;p&gt;It is a great book which contains a lot more information than I covered
here. Get it, it is well worth the money.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-7744918320648162029?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/7744918320648162029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=7744918320648162029' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7744918320648162029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7744918320648162029'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/05/ruby-exceptional-language.html' title='Ruby, an Exceptional Language'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-7351607115869739161</id><published>2011-05-15T09:49:00.011+02:00</published><updated>2011-05-20T07:27:31.320+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='node'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='nodejs'/><title type='text'>A Not Very Short Introduction To Node.js</title><content type='html'>&lt;p&gt;&lt;a href="http://nodejs.org/"&gt;Node.js&lt;/a&gt; is a set of asynchronous libraries, built
on top of the &lt;a href="http://code.google.com/p/v8/"&gt;Google V8 Javascript
Engine&lt;/a&gt;. Node is used for server side
development in Javascript. Do you feel the rush of the 90's coming
through your head. It is not the revival of
&lt;a href="http://docsrv.sco.com/INT_LiveWire/CONTENTS.html"&gt;LiveWire&lt;/a&gt;, Node is
a different beast. Node is a single threaded process, focused on doing
networking right. Right, in this case, means without blocking I/O. All
the libraries built for Node use non-blocking I/O. This is a really cool
feature, which allows the single thread in Node to serve thousands of
request per second. It even lets you run multiple servers in the same
thread. Check out the performance characteristics of Nginx and Apache
that utilize the same technique.&lt;/p&gt; 
 
&lt;p&gt;&lt;img src="http://www.webfaction.com/blog/nginx-apache-reqs-sec.png" title="Concurrency x Requests" alt="Concurrency x Requests" /&gt;&lt;/p&gt; 
 
&lt;p&gt;The graph for memory usage is even better.&lt;/p&gt; 
 
&lt;p&gt;&lt;img src="http://www.webfaction.com/blog/nginx-apache-memory.png" title="Concurrency x Memory" alt="Concurrency x Memory" /&gt;&lt;/p&gt; 
 
&lt;p&gt;Read more about it at the &lt;a href="http://blog.webfaction.com/a-little-holiday-present"&gt;Web Faction
Blog&lt;/a&gt;&lt;/p&gt; 
 
&lt;p&gt;OK, so what's the catch? The catch is that all code that does I/O, or
anything slow at all, has to be called in an asynchronous style.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Synchronous&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; result &lt;font color="#990000"&gt;=&lt;/font&gt; db&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;query&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"select * from T"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Use result&lt;/font&gt;&lt;/i&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Asynchronous&lt;/font&gt;&lt;/i&gt; 
db&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;query&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"select * from T"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;result&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;i&gt;&lt;font color="#9A1900"&gt;// Use result&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;So, all libraries that deal with IO has to be re-implemented with this
style of programming. The good news is that even though Node has only
been around for a couple of years, there are more than 1800 libraries
available. The libraries are of varying quality but the popularity of
Node shows good promise to deliver high-quality libraries for anything
that you can imagine.&lt;/p&gt; 
 
&lt;h2&gt;History&lt;/h2&gt; 
 
&lt;p&gt;Node is definitely not the first of its kind. The non-blocking
&lt;code&gt;select()&lt;/code&gt; loop, that is at the heart of Node, dates back to 1983.&lt;/p&gt; 
 
&lt;p&gt;&lt;a href="http://twistedmatrix.com/trac/"&gt;Twisted&lt;/a&gt; appeared in Python (2002) and
&lt;a href="http://rubyeventmachine.com/"&gt;EventMachine&lt;/a&gt; in Ruby (2003).&lt;/p&gt; 
 
&lt;p&gt;This year a couple of newcomers appeared.&lt;/p&gt; 
 
&lt;p&gt;&lt;a href="http://postrank-labs.github.com/goliath/"&gt;Goliath&lt;/a&gt;, which builds on
EventMachine, and uses fibers to allow us to program in an synchronous
style even though it is asynchronous under the hood.&lt;/p&gt; 
 
&lt;p&gt;And, the &lt;a href="http://msdn.microsoft.com/en-us/vstudio/gg316360"&gt;Async Framework in
.Net&lt;/a&gt;, which enhances
the compiler with the keywords &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; to allow for very
elegant asynchronous programming.&lt;/p&gt; 
 
&lt;h2&gt;Get Started&lt;/h2&gt; 
 
&lt;p&gt;This example uses OSX as an example platform, if you use something else
you will have to google for instructions.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Install Node using Homebrew&lt;/font&gt;&lt;/i&gt; 
$ brew install node
&lt;font color="#990000"&gt;==&amp;gt;&lt;/font&gt; Downloading http&lt;font color="#990000"&gt;:&lt;/font&gt;//nodejs&lt;font color="#990000"&gt;.&lt;/font&gt;org/dist/node-v&lt;font color="#993399"&gt;0.4&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;7&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;tar&lt;font color="#990000"&gt;.&lt;/font&gt;gz
&lt;i&gt;&lt;font color="#9A1900"&gt;######################################################################## 100.0%&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#990000"&gt;==&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;.&lt;/font&gt;/configure --prefix&lt;font color="#990000"&gt;=&lt;/font&gt;/usr/local/Cellar/node&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;0.4&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;7&lt;/font&gt; 
&lt;font color="#990000"&gt;==&amp;gt;&lt;/font&gt; make install
&lt;font color="#990000"&gt;==&amp;gt;&lt;/font&gt; Caveats
Please add /usr/local/lib/node to your NODE_PATH environment variable to have node libraries picked up&lt;font color="#990000"&gt;.&lt;/font&gt; 
&lt;font color="#990000"&gt;==&amp;gt;&lt;/font&gt; Summary
/usr/local/Cellar/node&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;0.4&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;7&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;72&lt;/font&gt; files&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;7&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;5M&lt;font color="#990000"&gt;,&lt;/font&gt; built &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; &lt;font color="#993399"&gt;1.2&lt;/font&gt; minutes
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;When installed you have access to the &lt;code&gt;node&lt;/code&gt; command-line command. When
invoked without arguments, it start a REPL.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ node
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;function hello&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;name&lt;font color="#990000"&gt;)&lt;/font&gt; {
&lt;font color="#990000"&gt;...&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;'hello '&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; name&lt;font color="#990000"&gt;;&lt;/font&gt; 
&lt;font color="#990000"&gt;...&lt;/font&gt; }
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; hello&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'tapir'&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
&lt;font color="#FF0000"&gt;'hello tapir'&lt;/font&gt; 
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;When invoked with a script it runs the script.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// hello.js&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    console&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;log&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'Tapir'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2000&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
console&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;log&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'Hello'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ node hello&lt;font color="#990000"&gt;.&lt;/font&gt;js
Hello
&lt;font color="#990000"&gt;...&lt;/font&gt; 
Tapir
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h2&gt;Networking&lt;/h2&gt; 
 
&lt;p&gt;As I mentioned above, Node is focused on networking. That means it
should be easy to write networking code. Here is a simple echo server.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Echo Server&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; net &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'net'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; server &lt;font color="#990000"&gt;=&lt;/font&gt; net&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;createServer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;socket&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    socket&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;on&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'data'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;data&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
        console&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;log&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;data&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;toString&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;());&lt;/font&gt; 
        socket&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;write&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;data&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
server&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;listen&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;4000&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;And here is a simple HTTP server.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// HTTP Server&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; http &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'http'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; web &lt;font color="#990000"&gt;=&lt;/font&gt; http&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;createServer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;request&lt;font color="#990000"&gt;,&lt;/font&gt; response&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  response&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;writeHead&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;200&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;'Content-Type'&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;'text/plain'&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
  response&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;end&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'Tapirs are beautiful!&lt;/font&gt;&lt;font color="#CC33CC"&gt;\n&lt;/font&gt;&lt;font color="#FF0000"&gt;'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
web&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;listen&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;4001&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Quite similar. A cool thing is that the servers can be started from the
same file and node will, happily, serve both HTTP and echo requests from
the same thread without any problems. Let's try them out!&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# curl the http service&lt;/font&gt;&lt;/i&gt; 
$ curl localhost&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;4001&lt;/font&gt; 
Tapirs are beautiful&lt;font color="#990000"&gt;!&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;# use netcat to send the string to the echo server&lt;/font&gt;&lt;/i&gt; 
$ echo &lt;font color="#FF0000"&gt;'Hello beautiful tapir'&lt;/font&gt; &lt;font color="#990000"&gt;|&lt;/font&gt; nc localhost &lt;font color="#993399"&gt;4000&lt;/font&gt; 
Hello beautiful tapir
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h2&gt;Modules&lt;/h2&gt; 
 
&lt;p&gt;Node comes with a selection of built in modules. Ryan Dahl says that
they try to keep the core small, but even so the built-in modules cover
a lot of useful functionality.&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;net - contains tcp/ip related networking functionality.&lt;/li&gt; 
&lt;li&gt;http - contains functionality for dealing with the HTTP protocol.&lt;/li&gt; 
&lt;li&gt;util - holds common utility functions, such as log, inherits, pump,
...&lt;/li&gt; 
&lt;li&gt;fs - contains filesystem related functionality, remember that
everything should be asynchronous.&lt;/li&gt; 
&lt;li&gt;events - contains the EventEmitter that is used for dealing with
events in a consistent way. It is used internally but it can be used
externally too.&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h3&gt;An example&lt;/h3&gt; 
 
&lt;p&gt;Here is an example of a simple module.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// module tapir.js&lt;/font&gt;&lt;/i&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// require another module&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; util &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'util'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;eat&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;food&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  util&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;log&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'eating '&lt;/font&gt;&lt;font color="#990000"&gt;+&lt;/font&gt; food&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// export a function&lt;/font&gt;&lt;/i&gt; 
exports&lt;font color="#990000"&gt;.&lt;/font&gt;eat &lt;font color="#990000"&gt;=&lt;/font&gt; eat&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;As you can see it looks like a normal Javascript file and it even looks
like it has global variables. It doesn't. When a module is loaded it is
wrapped in code, similar to this.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; module &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; exports&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;{}}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;module&lt;font color="#990000"&gt;,&lt;/font&gt; exports&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;i&gt;&lt;font color="#9A1900"&gt;// module code from file&lt;/font&gt;&lt;/i&gt; 
  &lt;font color="#990000"&gt;...&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;)(&lt;/font&gt;module&lt;font color="#990000"&gt;,&lt;/font&gt; module&lt;font color="#990000"&gt;.&lt;/font&gt;exports&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;As you can see the code is wrapped in a function and an empty object
with an &lt;code&gt;export&lt;/code&gt; property is sent into it. This is used by the file to
export only the functions that it want to publish.&lt;/p&gt; 
 
&lt;p&gt;The &lt;code&gt;require&lt;/code&gt; function works in symphony with the module and it returns
the exported functions to the caller.&lt;/p&gt; 
 
&lt;h3&gt;Node Package Manager, npm&lt;/h3&gt; 
 
&lt;p&gt;To allow simple handling of third-party packages, Node uses &lt;code&gt;npm&lt;/code&gt;. It
can be installed like this:&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ curl http&lt;font color="#990000"&gt;:&lt;/font&gt;//npmjs&lt;font color="#990000"&gt;.&lt;/font&gt;org/install&lt;font color="#990000"&gt;.&lt;/font&gt;sh &lt;font color="#990000"&gt;|&lt;/font&gt; sh
&lt;font color="#990000"&gt;...&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;And used like this:&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ npm install -g express
mime@&lt;font color="#993399"&gt;1.2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt; /usr/local/lib/node_modules/express/node_modules/mime
connect@&lt;font color="#993399"&gt;1.4&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt; /usr/local/lib/node_modules/express/node_modules/connect
qs@&lt;font color="#993399"&gt;0.1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt; /usr/local/lib/node_modules/express/node_modules/qs
/usr/local/bin/express -&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; /usr/local/lib/node_modules/express/bin/express
express@&lt;font color="#993399"&gt;2.3&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt; /usr/local/lib/node_modules/express
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;As you can see, installing a module also installs its dependencies. This
works because a module can be package with meta-data, like so:&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// express/package.json&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"name"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"express"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"description"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"Sinatra inspired web development framework"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"version"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"2.3.2"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"author"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"TJ Holowaychuk &amp;lt;tj@vision-media.ca&amp;gt;"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"contributors"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#FF0000"&gt;"name"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"TJ Holowaychuk"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"email"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"tj@vision-media.ca"&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#FF0000"&gt;"name"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"Guillermo Rauch"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"email"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"rauchg@gmail.com"&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
  &lt;font color="#990000"&gt;],&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"dependencies"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;"connect"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"&amp;gt;= 1.4.0 &amp;lt; 2.0.0"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;"mime"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"&amp;gt;= 0.0.1"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;"qs"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"&amp;gt;= 0.0.6"&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"keywords"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;"framework"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"sinatra"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"web"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"rest"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"restful"&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"repository"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"git://github.com/visionmedia/express"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"main"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"index"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"bin"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#FF0000"&gt;"express"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"./bin/express"&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;"engines"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#FF0000"&gt;"node"&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"&amp;gt;= 0.4.1 &amp;lt; 0.5.0"&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;The &lt;code&gt;package.json&lt;/code&gt; contains information about who made the module, its
dependencies, along with some additional information to enable better
searching facilities.&lt;/p&gt; 
 
&lt;p&gt;Npm installs the modules from &lt;a href="http://npm.mape.me/"&gt;a common
respository&lt;/a&gt;, which contains more than 1800
modules.&lt;/p&gt; 
 
&lt;h3&gt;Noteworthy Modules&lt;/h3&gt; 
 
&lt;p&gt;&lt;em&gt;Express&lt;/em&gt; is probably the most used of all third-party modules. It is
a Sinatra clone and it is very good, just like Sinatra.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Create a server&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; app &lt;font color="#990000"&gt;=&lt;/font&gt; express&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;createServer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
app&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;listen&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;4000&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Mount the root (/) and redirect to index&lt;/font&gt;&lt;/i&gt; 
app&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;get&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'/'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;req&lt;font color="#990000"&gt;,&lt;/font&gt; res&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  res&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;redirect&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'/index.html'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Handle a post to /quiz&lt;/font&gt;&lt;/i&gt; 
app&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;post&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'/quiz'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;req&lt;font color="#990000"&gt;,&lt;/font&gt; res&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  res&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;send&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;quiz&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;create&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;().&lt;/font&gt;id&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;toString&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;());&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Express uses &lt;em&gt;Connect&lt;/em&gt; to handle middleware. Middleware is like Rack
but for Node (No wonder that Node is nice to work with when it borrows
its ideas from Ruby :)&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000000"&gt;connect&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt; 
      &lt;i&gt;&lt;font color="#9A1900"&gt;// Add a logger&lt;/font&gt;&lt;/i&gt; 
      connect&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;logger&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; 
      &lt;i&gt;&lt;font color="#9A1900"&gt;// Serve static file from the current directory&lt;/font&gt;&lt;/i&gt; 
    &lt;font color="#990000"&gt;,&lt;/font&gt; connect&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;static&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;__dirname&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;i&gt;&lt;font color="#9A1900"&gt;// Compile Sass and Coffescript files, on the fly&lt;/font&gt;&lt;/i&gt; 
    &lt;font color="#990000"&gt;,&lt;/font&gt; connect&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;compiler&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt;enable&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;'sass'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'coffeescript'&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;i&gt;&lt;font color="#9A1900"&gt;// Profile all requests&lt;/font&gt;&lt;/i&gt; 
    &lt;font color="#990000"&gt;,&lt;/font&gt; connect&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;profiler&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; 
  &lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;listen&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;3000&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Another popular library is &lt;em&gt;Socket.IO&lt;/em&gt;. It handles the usual socket
variants, such as WebSocket, Comet, Flash Sockets, etc...&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; http &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'http'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; io &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'socket.io'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
server &lt;font color="#990000"&gt;=&lt;/font&gt; http&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;createServer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;req&lt;font color="#990000"&gt;,&lt;/font&gt; res&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#990000"&gt;...&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
server&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;listen&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;80&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// socket.io attaches to an existing server&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; socket &lt;font color="#990000"&gt;=&lt;/font&gt; io&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;listen&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;server&lt;font color="#990000"&gt;);&lt;/font&gt; 
socket&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;on&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'connection'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;client&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;i&gt;&lt;font color="#9A1900"&gt;// new client is here!&lt;/font&gt;&lt;/i&gt; 
  client&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;on&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'message'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; ... &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
  client&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;on&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'disconnect'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; ... &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;&lt;em&gt;MySql&lt;/em&gt; has a library for Node.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;client&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;query&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;'SELECT * FROM '&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; TEST_TABLE&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;i&gt;&lt;font color="#9A1900"&gt;// Note the callback style&lt;/font&gt;&lt;/i&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;,&lt;/font&gt; results&lt;font color="#990000"&gt;,&lt;/font&gt; fields&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;/b&gt; err&lt;font color="#990000"&gt;;&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
    console&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;log&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;results&lt;font color="#990000"&gt;);&lt;/font&gt; 
    console&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;log&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fields&lt;font color="#990000"&gt;);&lt;/font&gt; 
    client&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;end&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;And &lt;em&gt;Mongoose&lt;/em&gt; can be used for accessing MongoDB.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Declare the schema&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; Schema &lt;font color="#990000"&gt;=&lt;/font&gt; mongoose&lt;font color="#990000"&gt;.&lt;/font&gt;Schema
  &lt;font color="#990000"&gt;,&lt;/font&gt; ObjectId &lt;font color="#990000"&gt;=&lt;/font&gt; Schema&lt;font color="#990000"&gt;.&lt;/font&gt;ObjectId&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; BlogPost &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Schema&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    author    &lt;font color="#990000"&gt;:&lt;/font&gt; ObjectId
  &lt;font color="#990000"&gt;,&lt;/font&gt; title     &lt;font color="#990000"&gt;:&lt;/font&gt; String
  &lt;font color="#990000"&gt;,&lt;/font&gt; body      &lt;font color="#990000"&gt;:&lt;/font&gt; String
  &lt;font color="#990000"&gt;,&lt;/font&gt; date      &lt;font color="#990000"&gt;:&lt;/font&gt; Date
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Use it&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; BlogPost &lt;font color="#990000"&gt;=&lt;/font&gt; mongoose&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;model&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'BlogPost'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Save&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; post &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;BlogPost&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
post&lt;font color="#990000"&gt;.&lt;/font&gt;author &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;'Stravinsky'&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
instance&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;save&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;i&gt;&lt;font color="#9A1900"&gt;//&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Find&lt;/font&gt;&lt;/i&gt; 
BlogPost&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;find&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;,&lt;/font&gt; docs&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;i&gt;&lt;font color="#9A1900"&gt;// docs.forEach&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h3&gt;Templating Engines&lt;/h3&gt; 
 
&lt;p&gt;Everytime a new platform makes its presence, it brings along a couple of
new templating languages and Node is no different. Along with the
popular ones from the Ruby world, like Haml and Erb (EJS in Node),
comes some new ones like Jade and some browser templating languages like
Mustache and jQuery templates. I'll show examples of Jade and Mu
(Mustache for Node).&lt;/p&gt; 
 
&lt;p&gt;I like &lt;em&gt;Jade&lt;/em&gt;, because it is a Javascript dialect of Haml and it seems
appropriate to use if I'm using Javascript on the server side.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;font color="#990000"&gt;!!!&lt;/font&gt; &lt;font color="#993399"&gt;5&lt;/font&gt; 
&lt;b&gt;&lt;font color="#000000"&gt;html&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;lang&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"en"&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
  head
    title&lt;font color="#990000"&gt;=&lt;/font&gt; pageTitle
    &lt;b&gt;&lt;font color="#000000"&gt;script&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;type&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;'text/javascript'&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;foo&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;{&lt;/font&gt; 
        &lt;b&gt;&lt;font color="#000000"&gt;bar&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; 
      &lt;font color="#990000"&gt;}&lt;/font&gt; 
  body
    h1 Jade &lt;font color="#990000"&gt;-&lt;/font&gt; node template engine
    &lt;i&gt;&lt;font color="#9A1900"&gt;#container&lt;/font&gt;&lt;/i&gt; 
      &lt;font color="#990000"&gt;-&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;youAreUsingJade&lt;font color="#990000"&gt;)&lt;/font&gt; 
        p You are amazing
      &lt;font color="#990000"&gt;-&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt; 
        p Get on it&lt;font color="#990000"&gt;!&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;I'm not really sure if I like Mustache or not, but I can surely see the
value of having a templating language which works both on the server side
and in the browser.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;h1&amp;gt;&lt;/font&gt;&lt;/b&gt;{{header}}&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/h1&amp;gt;&lt;/font&gt;&lt;/b&gt; 
{{#bug}}
{{/bug}}
 
{{#items}}
  {{#first}}
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;&lt;/font&gt;&lt;/b&gt;{{name}}&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/strong&amp;gt;&amp;lt;/li&amp;gt;&lt;/font&gt;&lt;/b&gt; 
  {{/first}}
  {{#link}}
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;href&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"{{url}}"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;{{name}}&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/font&gt;&lt;/b&gt; 
  {{/link}}
{{/items}}
 
{{#empty}}
  &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;p&amp;gt;&lt;/font&gt;&lt;/b&gt;The list is empty.&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/p&amp;gt;&lt;/font&gt;&lt;/b&gt; 
{{/empty}}
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h2&gt;Testing&lt;/h2&gt; 
 
&lt;p&gt;Node comes with assertions built in, and all testing frameworks build on
the Assert module, so it is good to know.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;ok&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;value&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;message&lt;font color="#990000"&gt;]);&lt;/font&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;equal&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;actual&lt;font color="#990000"&gt;,&lt;/font&gt; expected&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;message&lt;font color="#990000"&gt;])&lt;/font&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;notEqual&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;actual&lt;font color="#990000"&gt;,&lt;/font&gt; expected&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;message&lt;font color="#990000"&gt;])&lt;/font&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;deepEqual&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;actual&lt;font color="#990000"&gt;,&lt;/font&gt; expected&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;message&lt;font color="#990000"&gt;])&lt;/font&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;strictEqual&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;actual&lt;font color="#990000"&gt;,&lt;/font&gt; expected&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;message&lt;font color="#990000"&gt;])&lt;/font&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;throws&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;block&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;error&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;message&lt;font color="#990000"&gt;])&lt;/font&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;doesNotThrow&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;block&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;error&lt;font color="#990000"&gt;],&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;message&lt;font color="#990000"&gt;])&lt;/font&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;ifError&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;value&lt;font color="#990000"&gt;)&lt;/font&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;fail&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;actual&lt;font color="#990000"&gt;,&lt;/font&gt; expected&lt;font color="#990000"&gt;,&lt;/font&gt; message&lt;font color="#990000"&gt;,&lt;/font&gt; operator&lt;font color="#990000"&gt;)&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Example&lt;/font&gt;&lt;/i&gt; 
&lt;i&gt;&lt;font color="#9A1900"&gt;// assert.throws(function, regexp)&lt;/font&gt;&lt;/i&gt; 
assert&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;throws&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Error&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"Wrong value"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;font color="#FF6600"&gt;/value/&lt;/font&gt; 
&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Apart from that there are at least 30 different testing frameworks to
use. I have chosen to use NodeUnit since I find that it handles
asynchronous testing well, and it has a nice UTF-8 output that looks
good in the terminal,&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// ./test/test-doubled.js&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; doubled &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'../lib/doubled'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Exported functions are run by the test runner&lt;/font&gt;&lt;/i&gt; 
exports&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;'calculate'&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;test&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    test&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;equal&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;doubled&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;calculate&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;font color="#993399"&gt;4&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
    test&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;done&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// An asynchronous test&lt;/font&gt;&lt;/i&gt; 
exports&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;'read a number'&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;test&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    test&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;expect&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// Make sure the assertion is run&lt;/font&gt;&lt;/i&gt; 
 
    &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; ev &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; events&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;EventEmitter&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
    process&lt;font color="#990000"&gt;.&lt;/font&gt;openStdin &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; ev&lt;font color="#990000"&gt;;&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
    process&lt;font color="#990000"&gt;.&lt;/font&gt;exit &lt;font color="#990000"&gt;=&lt;/font&gt; test&lt;font color="#990000"&gt;.&lt;/font&gt;done&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
    console&lt;font color="#990000"&gt;.&lt;/font&gt;log &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;str&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
        test&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;equal&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;str&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'Doubled: 24'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
    doubled&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;read&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
    ev&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;emit&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'data'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'12'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 

&lt;p&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 245px; height: 156px;" src="http://3.bp.blogspot.com/-UdENjhkKWAo/Tc-GNMPxoTI/AAAAAAAAAAc/LIbkiZpOfNM/s320/nodeunit.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5606847622283370802" /&gt;&lt;/p&gt; 
 
&lt;h2&gt;Deployment&lt;/h2&gt; 
 
&lt;p&gt;There are already a lot of platforms providing Node as a service (PaaS
, Platform as a Service). Most of them are using
&lt;a href="http://heroku.com"&gt;Heroku&lt;/a&gt; style deployment by pushing to a Git remote.
I'll show three alternatives that all provide free Node hosting.&lt;/p&gt; 
 
&lt;h3&gt;Joyent (no.de)&lt;/h3&gt; 
 
&lt;p&gt;Joyent, the employers of Ryan Dahl, give you &lt;code&gt;ssh&lt;/code&gt; access so that you
can install the modules you need. Deployment is done by pushing to
a Git remote.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ ssh node@my-machine&lt;font color="#990000"&gt;.&lt;/font&gt;no&lt;font color="#990000"&gt;.&lt;/font&gt;de
$ nmp install express
$ git remote add node node@andersjanmyr&lt;font color="#990000"&gt;.&lt;/font&gt;no&lt;font color="#990000"&gt;.&lt;/font&gt;de&lt;font color="#990000"&gt;:&lt;/font&gt;repo
$ git push node master
Counting objects&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;5&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;done&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt; 
Delta compression using up to &lt;font color="#993399"&gt;2&lt;/font&gt; threads&lt;font color="#990000"&gt;.&lt;/font&gt; 
Compressing objects&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;100&lt;/font&gt;&lt;font color="#990000"&gt;%&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;done&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt; 
Writing objects&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;100&lt;/font&gt;&lt;font color="#990000"&gt;%&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;font color="#993399"&gt;321&lt;/font&gt; bytes&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;done&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt; 
Total &lt;font color="#993399"&gt;3&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;delta &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; reused &lt;font color="#993399"&gt;0&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;delta &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt; Starting node v0&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;4.7&lt;/font&gt;&lt;font color="#990000"&gt;...&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt; Successful
To node@andersjanmyr&lt;font color="#990000"&gt;.&lt;/font&gt;no&lt;font color="#990000"&gt;.&lt;/font&gt;de&lt;font color="#990000"&gt;:&lt;/font&gt;repo
  8f59169&lt;font color="#990000"&gt;..&lt;/font&gt;c1177b0  master -&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; master
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h3&gt;Nodester&lt;/h3&gt; 
 
&lt;p&gt;Nodester, gives you a command line tool, &lt;code&gt;nodester&lt;/code&gt;, that you use to
install modules. Deployment by pushing to a Git remote.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ nodester npm install express
$ git push nodester master
Counting objects&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;5&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;done&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt; 
Delta compression using up to &lt;font color="#993399"&gt;2&lt;/font&gt; threads&lt;font color="#990000"&gt;.&lt;/font&gt; 
Compressing objects&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;100&lt;/font&gt;&lt;font color="#990000"&gt;%&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;done&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt; 
Writing objects&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;100&lt;/font&gt;&lt;font color="#990000"&gt;%&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;font color="#993399"&gt;341&lt;/font&gt; bytes&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;done&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt; 
Total &lt;font color="#993399"&gt;3&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;delta &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; reused &lt;font color="#993399"&gt;0&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;delta &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt; Syncing repo with chroot
remote&lt;font color="#990000"&gt;:&lt;/font&gt; From /node/hosted_apps/andersjanmyr&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;1346&lt;/font&gt;-7856c14e6a5d92a6b5374ec4772a6da0&lt;font color="#990000"&gt;.&lt;/font&gt;git&lt;font color="#990000"&gt;/.&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt;    38f4e6e&lt;font color="#990000"&gt;..&lt;/font&gt;8f59169  master     -&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; origin/master
remote&lt;font color="#990000"&gt;:&lt;/font&gt; Updating 38f4e6e&lt;font color="#990000"&gt;..&lt;/font&gt;8f59169
remote&lt;font color="#990000"&gt;:&lt;/font&gt; Fast-forward
remote&lt;font color="#990000"&gt;:&lt;/font&gt;  Gemfile&lt;font color="#990000"&gt;.&lt;/font&gt;lock &lt;font color="#990000"&gt;|&lt;/font&gt;   &lt;font color="#993399"&gt;10&lt;/font&gt; &lt;font color="#990000"&gt;++++&lt;/font&gt;------
remote&lt;font color="#990000"&gt;:&lt;/font&gt;  &lt;font color="#993399"&gt;1&lt;/font&gt; files changed&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;4&lt;/font&gt; insertions&lt;font color="#990000"&gt;(+),&lt;/font&gt; &lt;font color="#993399"&gt;6&lt;/font&gt; deletions&lt;font color="#990000"&gt;(&lt;/font&gt;-&lt;font color="#990000"&gt;)&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt; Checking &lt;font color="#990000"&gt;./.&lt;/font&gt;git/hooks/post-receive
remote&lt;font color="#990000"&gt;:&lt;/font&gt; Attempting to restart your app&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;1346&lt;/font&gt;-7856c14e6a5d92a6b5374ec4772a6da0
remote&lt;font color="#990000"&gt;:&lt;/font&gt; App restarted&lt;font color="#990000"&gt;..&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt;     &lt;font color="#990000"&gt;\&lt;/font&gt;m&lt;font color="#990000"&gt;/&lt;/font&gt; Nodester out &lt;font color="#990000"&gt;\&lt;/font&gt;m&lt;font color="#990000"&gt;/&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt; 
remote&lt;font color="#990000"&gt;:&lt;/font&gt; 
To ec2-user@nodester&lt;font color="#990000"&gt;.&lt;/font&gt;com&lt;font color="#990000"&gt;:&lt;/font&gt;/node/hosted_apps/andersjanmyr&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;1346&lt;/font&gt;-7856c14e6a5d92a6b5374ec4772a6da0&lt;font color="#990000"&gt;.&lt;/font&gt;git
   38f4e6e&lt;font color="#990000"&gt;..&lt;/font&gt;8f59169  master -&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; master
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h3&gt;Cloud Foundry&lt;/h3&gt; 
 
&lt;p&gt;Cloud Foundry is one of the most interesting platforms in the cloud.  It
was genius by VM Ware to open source the platform, allowing anyone to
set up their own cloud if they wish. If you don't want to setup your own
Cloud Foundry Cloud, you can use the service hosted at
cloundfoundry.com.&lt;/p&gt; 
 
&lt;p&gt;With Cloud Foundry, you install the modules locally and then they are
automatically deployed as part of the &lt;code&gt;vmc push&lt;/code&gt;. Push in this case does
not mean &lt;code&gt;git push&lt;/code&gt;, but instead, copy all the files from my local machine
to the server.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ npm install express  &lt;i&gt;&lt;font color="#9A1900"&gt;# Install locally&lt;/font&gt;&lt;/i&gt; 
mime@&lt;font color="#993399"&gt;1.2&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt; &lt;font color="#990000"&gt;.&lt;/font&gt;/node_modules/express/node_modules/mime
connect@&lt;font color="#993399"&gt;1.4&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt; &lt;font color="#990000"&gt;.&lt;/font&gt;/node_modules/express/node_modules/connect
qs@&lt;font color="#993399"&gt;0.1&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt; &lt;font color="#990000"&gt;.&lt;/font&gt;/node_modules/express/node_modules/qs
express@&lt;font color="#993399"&gt;2.3&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt; &lt;font color="#990000"&gt;.&lt;/font&gt;/node_modules/express
 
$ vmc push
Would you like to deploy from the current directory&lt;font color="#990000"&gt;?&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;Yn&lt;font color="#990000"&gt;]:&lt;/font&gt; Y
Application Name&lt;font color="#990000"&gt;:&lt;/font&gt; snake
Application Deployed URL&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;'snake.cloudfoundry.com'&lt;/font&gt;&lt;font color="#990000"&gt;?&lt;/font&gt; 
Detected a Node&lt;font color="#990000"&gt;.&lt;/font&gt;js Application&lt;font color="#990000"&gt;,&lt;/font&gt; is this correct&lt;font color="#990000"&gt;?&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;Yn&lt;font color="#990000"&gt;]:&lt;/font&gt; 
Memory Reservation &lt;font color="#990000"&gt;[&lt;/font&gt;Default&lt;font color="#990000"&gt;:&lt;/font&gt;64M&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;64M&lt;font color="#990000"&gt;,&lt;/font&gt; 128M&lt;font color="#990000"&gt;,&lt;/font&gt; 256M&lt;font color="#990000"&gt;,&lt;/font&gt; 512M&lt;font color="#990000"&gt;,&lt;/font&gt; 1G or 2G&lt;font color="#990000"&gt;)&lt;/font&gt; 
Creating Application&lt;font color="#990000"&gt;:&lt;/font&gt; OK
Would you like to &lt;b&gt;&lt;font color="#0000FF"&gt;bind&lt;/font&gt;&lt;/b&gt; any services to &lt;font color="#FF0000"&gt;'snake'&lt;/font&gt;&lt;font color="#990000"&gt;?&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;yN&lt;font color="#990000"&gt;]:&lt;/font&gt; 
Uploading Application&lt;font color="#990000"&gt;:&lt;/font&gt; 
  Checking &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; available resources&lt;font color="#990000"&gt;:&lt;/font&gt; OK
  Packing application&lt;font color="#990000"&gt;:&lt;/font&gt; OK
  Uploading &lt;font color="#990000"&gt;(&lt;/font&gt;1K&lt;font color="#990000"&gt;):&lt;/font&gt; OK
Push Status&lt;font color="#990000"&gt;:&lt;/font&gt; OK
Staging Application&lt;font color="#990000"&gt;:&lt;/font&gt; OK
Starting Application&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#990000"&gt;........&lt;/font&gt;OK
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h2&gt;Tools&lt;/h2&gt; 
 
&lt;p&gt;There are of course a bunch of tools that come with a new platform,
Jake, is a Javascript version of Rake, but I am happy with Rake and
I don't see the need to switch. But, there are some tools that I cannot
live without when using Node.&lt;/p&gt; 
 
&lt;h3&gt;Reloaders&lt;/h3&gt; 
 
&lt;p&gt;If you use the vanilla &lt;code&gt;node&lt;/code&gt; command then you have to restart it
every time you make a change to a file. That is awfully annoying and
there are already a number of solutions to the problem.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Nodemon watches the files in your directory and reloads them if necessary&lt;/font&gt;&lt;/i&gt; 
$ npm install nodemon
nodemon@&lt;font color="#993399"&gt;0.3&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt; &lt;font color="#990000"&gt;..&lt;/font&gt;/node_modules/nodemon
 
$ nodemon server&lt;font color="#990000"&gt;.&lt;/font&gt;js 
&lt;font color="#993399"&gt;30&lt;/font&gt; Apr &lt;font color="#993399"&gt;08&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;21&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;23&lt;/font&gt; - &lt;font color="#990000"&gt;[&lt;/font&gt;nodemon&lt;font color="#990000"&gt;]&lt;/font&gt; running server&lt;font color="#990000"&gt;.&lt;/font&gt;js 
&lt;font color="#990000"&gt;...&lt;/font&gt; 
&lt;i&gt;&lt;font color="#9A1900"&gt;# Saving the file&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#993399"&gt;30&lt;/font&gt; Apr &lt;font color="#993399"&gt;08&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;22&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;01&lt;/font&gt; - &lt;font color="#990000"&gt;[&lt;/font&gt;nodemon&lt;font color="#990000"&gt;]&lt;/font&gt; restarting due to changes&lt;font color="#990000"&gt;...&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;# Alternative&lt;/font&gt;&lt;/i&gt; 
$ npm install supervisor
$ supervisor server&lt;font color="#990000"&gt;.&lt;/font&gt;js 
DEBUG&lt;font color="#990000"&gt;:&lt;/font&gt; Watching directory &lt;font color="#FF0000"&gt;'/evented-programming-with-nodejs/. &lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h3&gt;Debuggers&lt;/h3&gt; 
 
&lt;p&gt;Another tool that it is hard to live without is a debugger. Node comes
with one built in. It has a &lt;code&gt;gdb&lt;/code&gt; flavor to it and it is kind of rough.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ node debug server&lt;font color="#990000"&gt;.&lt;/font&gt;js
debug&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; run
debugger listening on port &lt;font color="#993399"&gt;5858&lt;/font&gt; 
connecting&lt;font color="#990000"&gt;...&lt;/font&gt;ok
&lt;b&gt;&lt;font color="#0000FF"&gt;break&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;#&amp;lt;Socket&amp;gt; ./server.js:9&lt;/font&gt;&lt;/i&gt; 
    debugger&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
debug&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; p data&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;toString()&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
tapir
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Javascript&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; echo &lt;font color="#990000"&gt;=&lt;/font&gt; net&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;createServer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;socket&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  socket&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;on&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'data'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;data&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;debugger&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// &amp;lt;= break into debugger&lt;/font&gt;&lt;/i&gt; 
      socket&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;write&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;data&lt;font color="#990000"&gt;);&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;If you want a GUI debugger, it is possible to use the one that comes with
Chrome by installing the &lt;code&gt;node-inspector&lt;/code&gt;. It is started similarly to
the built in debugger, but the &lt;code&gt;--debug&lt;/code&gt; is an option instead of
a subcommand.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ node-inspector &lt;font color="#990000"&gt;&amp;amp;&lt;/font&gt; 
visit http&lt;font color="#990000"&gt;://&lt;/font&gt;&lt;font color="#993399"&gt;0.0&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;0.0&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;8080&lt;/font&gt;/debug&lt;font color="#990000"&gt;?&lt;/font&gt;&lt;font color="#009900"&gt;port&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#993399"&gt;5858&lt;/font&gt; to start debugging
 
$ node --debug server&lt;font color="#990000"&gt;.&lt;/font&gt;js debugger listening on port &lt;font color="#993399"&gt;5858&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;After that you can just fire up Chrome on the URL,
&lt;a href="http://0.0.0.0:8080/debug?port=5858"&gt; http://0.0.0.0:8080/debug?port=5858&lt;/a&gt; and you can debug the node process
just as if it was running in the browser.&lt;/p&gt; 
 
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-Rc_zg7FdRQ4/Tc-GqIh9mbI/AAAAAAAAAAk/VjLI1a3_r0Y/s1600/nodeJS-Inspector.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 221px;" src="http://3.bp.blogspot.com/-Rc_zg7FdRQ4/Tc-GqIh9mbI/AAAAAAAAAAk/VjLI1a3_r0Y/s320/nodeJS-Inspector.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5606848119502117298" /&gt;&lt;/a&gt;&lt;/p&gt; 
 
&lt;h2&gt;Idioms&lt;/h2&gt; 
 
&lt;p&gt;Idioms, patterns, techniques, call it what you like. Javascript code is
littered with callbacks, and event more so with Node. Here are some tips
on how to write good asynchronous code with Node.&lt;/p&gt; 
 
&lt;h3&gt;Return on Callbacks&lt;/h3&gt; 
 
&lt;p&gt;It is easy to forget to escape from the function after a callback has
been called. An easy way to remedy this problem is to call return before
every call to a callback. Even though the value is never used by the
caller, it is an easy pattern to recognize and it prevents bugs.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;doSomething&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;response&lt;font color="#990000"&gt;,&lt;/font&gt; callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#000000"&gt;doAsyncCall&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'tapir'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;,&lt;/font&gt; result&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
      &lt;i&gt;&lt;font color="#9A1900"&gt;// return on the callback&lt;/font&gt;&lt;/i&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
    &lt;i&gt;&lt;font color="#9A1900"&gt;// return on the callback&lt;/font&gt;&lt;/i&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;null&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; result&lt;font color="#990000"&gt;);&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h3&gt;Exceptions in Callbacks&lt;/h3&gt; 
 
&lt;p&gt;Exceptions that occur in callbacks cannot be handled the way we are used
to, since the context is different. The solution to this is to pass
along the exception as a parameter to the callback. In Node the
convetion is to pass the error as the first parameter into the callback.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;insertIntoTable&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;row&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;,&lt;/font&gt; data&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;);&lt;/font&gt; 
  &lt;font color="#990000"&gt;...&lt;/font&gt; 
 
  &lt;i&gt;&lt;font color="#9A1900"&gt;// Everything is OK&lt;/font&gt;&lt;/i&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;null&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'row inserted'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h3&gt;Parallel Execution&lt;/h3&gt; 
 
&lt;p&gt;If you have multiple tasks that need to be finished before you take some
new action, this can be handled with a simple counter. Here is an
example of a simple function that starts up a bunch of functions in
parallel and waits for all of them to finish before calling the
callback.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Do all in parallel&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;doAll&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;collection&lt;font color="#990000"&gt;,&lt;/font&gt; callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; left &lt;font color="#990000"&gt;=&lt;/font&gt; collection&lt;font color="#990000"&gt;.&lt;/font&gt;length&lt;font color="#990000"&gt;;&lt;/font&gt; 
  collection&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;forEach&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fun&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;fun&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(--&lt;/font&gt;left &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Use it&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; result &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;[];&lt;/font&gt; 
&lt;b&gt;&lt;font color="#000000"&gt;doAll&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;([&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;result&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;push&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2000&lt;/font&gt; &lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;result&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;push&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;3000&lt;/font&gt; &lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;result&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;push&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;1000&lt;/font&gt; &lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
  &lt;font color="#990000"&gt;],&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; result&lt;font color="#990000"&gt;;&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// returns [3, 1, 2]&lt;/font&gt;&lt;/i&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h3&gt;Sequential Execution&lt;/h3&gt; 
 
&lt;p&gt;Sometimes the ordering is important. Here is a simple function that
makes sure that the calls are executed in sequence. It uses recursion to
to make sure that the calls are handled in the correct order. It also
uses the Node function &lt;code&gt;process.nextTick()&lt;/code&gt; to prevent the stack from
getting to large for large collections. Similar results can be obtained
with &lt;code&gt;setTimeout()&lt;/code&gt; in browser Javascript. It can be seen as a simple
trick to achieve &lt;em&gt;tail recursion&lt;/em&gt;.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;doInSequence&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;collection&lt;font color="#990000"&gt;,&lt;/font&gt; callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; queue &lt;font color="#990000"&gt;=&lt;/font&gt; collection&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;slice&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// Duplicate&lt;/font&gt;&lt;/i&gt; 
 
    &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;iterate&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;queue&lt;font color="#990000"&gt;.&lt;/font&gt;length &lt;font color="#990000"&gt;===&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
      &lt;i&gt;&lt;font color="#9A1900"&gt;// Take the first element&lt;/font&gt;&lt;/i&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; fun &lt;font color="#990000"&gt;=&lt;/font&gt; queue&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;splice&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;)[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;];&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#000000"&gt;fun&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
        &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;/b&gt; err&lt;font color="#990000"&gt;;&lt;/font&gt; 
        &lt;i&gt;&lt;font color="#9A1900"&gt;// Call it without building up the stack&lt;/font&gt;&lt;/i&gt; 
        process&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;nextTick&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;iterate&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
      &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;iterate&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; result &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;[];&lt;/font&gt; 
&lt;b&gt;&lt;font color="#000000"&gt;doInSequence&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;([&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;result&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;push&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2000&lt;/font&gt; &lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;result&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;push&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;3000&lt;/font&gt; &lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;result&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;push&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;1000&lt;/font&gt; &lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
  &lt;font color="#990000"&gt;],&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; result&lt;font color="#990000"&gt;;&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Returns [1, 2, 3]&lt;/font&gt;&lt;/i&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h2&gt;Library Support for Asynchronous Programming&lt;/h2&gt; 
 
&lt;p&gt;If you don't want to write these functions yourself, there are a few
libraries that can help you out. I'll show two version that I like.&lt;/p&gt; 
 
&lt;h3&gt;Fibers&lt;/h3&gt; 
 
&lt;p&gt;Fibers are also called co-routines. Fibers provide two functions,
&lt;em&gt;suspend&lt;/em&gt; and &lt;em&gt;resume&lt;/em&gt;, which allows us to write code in a synchronous
looking style. In the Node version of fibers,
&lt;a href="https://github.com/laverdet/node-fibers"&gt;node-fibers&lt;/a&gt;, suspend and
resume are called &lt;code&gt;yield()&lt;/code&gt; and &lt;code&gt;run()&lt;/code&gt; instead.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'fibers'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; print &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'util'&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;print&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;sleep&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;ms&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; fiber &lt;font color="#990000"&gt;=&lt;/font&gt; Fiber&lt;font color="#990000"&gt;.&lt;/font&gt;current&lt;font color="#990000"&gt;;&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; fiber&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;run&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; ms&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;yield&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
&lt;b&gt;&lt;font color="#000000"&gt;Fiber&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;print&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'wait... '&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; Date &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;font color="#FF0000"&gt;'&lt;/font&gt;&lt;font color="#CC33CC"&gt;\n&lt;/font&gt;&lt;font color="#FF0000"&gt;'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;sleep&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1000&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;print&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'ok... '&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; Date &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;font color="#FF0000"&gt;'&lt;/font&gt;&lt;font color="#CC33CC"&gt;\n&lt;/font&gt;&lt;font color="#FF0000"&gt;'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;run&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
&lt;b&gt;&lt;font color="#000000"&gt;print&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'back in main&lt;/font&gt;&lt;font color="#CC33CC"&gt;\n&lt;/font&gt;&lt;font color="#FF0000"&gt;'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Fibers are a very nice way of writing asynchronous code but, in Node,
they have one drawback. They are not supported without patching the V8
virtual machine. The patching is done when you install &lt;code&gt;node-fibers&lt;/code&gt; and
you have to run the command &lt;code&gt;node-fibers&lt;/code&gt; instead of &lt;code&gt;node&lt;/code&gt; to use it.&lt;/p&gt; 
 
&lt;h3&gt;The &lt;code&gt;async&lt;/code&gt; Library&lt;/h3&gt; 
 
&lt;p&gt;If you don't want to use the patched version of V8, I can recommend the
&lt;a href="https://github.com/caolan/async"&gt;async&lt;/a&gt; library.  Async provides
around 20 functions that include the usual 'functional' suspects (map,
reduce, filter, forEach...) as well as some common patterns for
asynchronous flow control (parallel, series, waterfall...). All these
functions assume you follow the Node convention of providing a single
callback as the last argument of your async function.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;async&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;map&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;([&lt;/font&gt;&lt;font color="#FF0000"&gt;'file1'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#FF0000"&gt;'file2'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#FF0000"&gt;'file3'&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; fs&lt;font color="#990000"&gt;.&lt;/font&gt;stat&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;,&lt;/font&gt; results&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;i&gt;&lt;font color="#9A1900"&gt;// results is now an array of stats for each file&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
async&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;filter&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;([&lt;/font&gt;&lt;font color="#FF0000"&gt;'file1'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#FF0000"&gt;'file2'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;&lt;font color="#FF0000"&gt;'file3'&lt;/font&gt;&lt;font color="#990000"&gt;],&lt;/font&gt; path&lt;font color="#990000"&gt;.&lt;/font&gt;exists&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;results&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;i&gt;&lt;font color="#9A1900"&gt;// results now equals an array of the existing files&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
async&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;parallel&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;([&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#990000"&gt;...&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#990000"&gt;...&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
&lt;font color="#990000"&gt;],&lt;/font&gt; callback&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
async&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;series&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;([&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#990000"&gt;...&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#990000"&gt;...&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
&lt;font color="#990000"&gt;],&lt;/font&gt; callback&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h2&gt;Conclusion&lt;/h2&gt; 
 
&lt;p&gt;Node is definitely an interesting platform. The possibility to have
Javascript running through the whole stack, from the browser all the way
down into the database (if you use something like CouchDB or MongoDB)
really appeals to me. The easy way to deploy code to multiple, different
cloud providers is also a good argument for Node.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-7351607115869739161?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/7351607115869739161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=7351607115869739161' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7351607115869739161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7351607115869739161'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/05/not-very-short-introduction-to-nodejs.html' title='A Not Very Short Introduction To Node.js'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-UdENjhkKWAo/Tc-GNMPxoTI/AAAAAAAAAAc/LIbkiZpOfNM/s72-c/nodeunit.png' height='72' width='72'/><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-1237263625156985694</id><published>2011-05-08T10:52:00.007+02:00</published><updated>2011-05-08T11:05:31.339+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mastery'/><category scheme='http://www.blogger.com/atom/ns#' term='mind'/><title type='text'>Mastery</title><content type='html'>&lt;p&gt;Here is a wonderful story, told by Ken Robinson in his book &lt;a href="http://www.amazon.com/Element-Finding-Passion-Changes-Everything/dp/0670020478?tag=thtasta-20"&gt;The
Element&lt;/a&gt;,
about an 8 year old girl, Gillian Lynne, who everyone sees as
a problem child.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Gillian and her mother went to a psychiatrist and the mother describes
her daughter's difficulties with concentrating, sitting, and doing her
homework.&lt;/p&gt;

&lt;p&gt;The doctor listened to the mother and then he told Gillian that he
wanted to talk to her mother alone.  When they left the room, the
doctor turned on some music on the radio. Outside the room, the doctor
said to the mother "Just stand her and watch her!" As they watched,
the girl started moving to the music with a grace that anyone would
have been impressed by.&lt;/p&gt;

&lt;p&gt;After watching for a few minutes, the doctor turned to the mother and
said: "There is nothing wrong with your daughter, she's a dancer, take
her to a dance school!"&lt;/p&gt;

&lt;p&gt;Gillan grew up to become one of the most accomplished choreographers
of our time.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This is a story about how people shine when they are allowed to do what
they are meant to do, when they are in their element. But, what it does
not take into account is work, hard work!&lt;/p&gt;

&lt;p&gt;Thomas Jefferson put it nicely:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;I find that the harder I work, the more luck I seem to have!&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This post is not about talent, it is about mastery, the hard work of
mastery!&lt;/p&gt;

&lt;p&gt;Talent is not a requirement for Mastery, in fact talent can get in your
way on the path of mastery, if it is too easy in the beginning we may
not be able to put in the hours needed for true mastery when it get hard
or boring.&lt;/p&gt;

&lt;p&gt;Many of the ideas for this post come from the book called
&lt;a href="http://www.amazon.com/Mastery-Keys-Success-Long-Term-Fulfillment/dp/0452267560?tag=thtasta-20"&gt;Mastery&lt;/a&gt;
by George Leonard and he describes it well.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;We fail to realize that mastery is not about perfection. It's about
a process, a journey. The master is the one who stays on the path day
after day, year after year. The master is the one who is willing to
try, and fail, and try again, for as long as he or she lives.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Leonard identifies five keys to mastery. They are instruction, practice,
surrender, intentionality, and the Edge.&lt;/p&gt;

&lt;h2&gt;Instruction&lt;/h2&gt;

&lt;p&gt;Instruction is vital. How do we know that what we are doing is the right
thing. As a programmer I am always confronted with new things. How do
I tell the good from the bad? After you reach a certain level of
experience it gets easier to make an educated guess, but it is still
just a guess. And before we have a lot of experience, we are liable to
fall into traps all the time, (EJB anyone?).&lt;/p&gt;

&lt;p&gt;My way of dealing with new things is to read books, papers, and blogs,
listen to podcasts, watch screencasts, and if I can find the time, attend
workshops at conferences. But, it is important to listen to critique as
well as praise of a new technique. If it seems reasonable to you, by all
means, give it a shot. And then, not until you have actually used
a system for quite a while, can you tell if it is good or not for you.
Because that is another aspect of mastery, we are all on our own path,
what is right for me may not be right for someone else!&lt;/p&gt;

&lt;h2&gt;Practice&lt;/h2&gt;

&lt;p&gt;Practice is the true essence of Mastery. Without it, everything else
falls to pieces. Practice is the path that build the foundation for
mastery. Another quote from Leonard:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;How do you best move toward mastery? To put it simply, you practice
diligently, but you practice primarily for the sake of the practice
itself.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;An interesting fact about practice is how the normal learning curve
looks.&lt;/p&gt;

&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 34px;" src="http://1.bp.blogspot.com/-vsjBDzXHvQo/TcZaL2EdtWI/AAAAAAAAAAU/W6s04Ke-3WY/s320/practice_curve.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5604265945848460642" /&gt;

&lt;p&gt;Do you recognize it? Long periods where you practice and practice but
you don't seem to get any better. Then suddenly there is a small
improvement and you feel like you finally get it, and then after
a little while you are back to normal again.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The more I know, the more I know that I don't know. --Socrates
(misquoted:)&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;Surrender&lt;/h2&gt;

&lt;p&gt;What Leonard calls surrender I would call humility. A Zen Master would
probably call it &lt;em&gt;Beginners Mind&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Beginner's Mind. It refers to having an attitude of openness, eagerness,
and lack of preconceptions when studying a subject, even when studying
at an advanced level, just as a beginner in that subject would.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;It can be very hard to give up your hard earned skills in order to grasp
a new concept. But, sometimes, the only way to improve is to start over
with a completely different approach.&lt;/p&gt;

&lt;p&gt;How do we expect to learn something new if we are not willing to look
like an idiot for awhile?&lt;/p&gt;

&lt;h2&gt;Intentionality&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;You gotta be careful if you don't know where you're going, because you
might not get there. -- Yogi Berra&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Intentionality means a lot of things. It means character, discipline,
stamina or willpower. But it also means knowing what you want.&lt;/p&gt;

&lt;p&gt;Do you know what you want? Unless you do, it is very hard to stay on the
path. In my mind intentionality is not necessarily goals, it is more
a direction. If I stop for a while and look around, I can tell if I am
on the path, because if I am, I will, slowly, be moving in the direction
I intend to go.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;When you get to the top of the mountain, keep climbing. -- Chinese
proverb&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;The Edge&lt;/h2&gt;

&lt;p&gt;Here's another quote that I like, from the book,
&lt;a href="http://www.amazon.com/Zorba-Greek-Nikos-Kazantzakis/dp/0684825546?tag=thtasta-20"&gt;Zorba&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;No you're not free! The string that you are tied to is perhaps longer
than others'. You're on a long piece of string boss, but you never cut
the string in two, you need a touch of folly to do that...
A man's head is like a grocer, it keeps accounts. It never risks all
it has, always keeps something in reserve. It never breaks the string.
But if a man never breaks the string, tell me what flavor is left in
life? Nothing, but the flavor of weak camomile tea. Nothing like rum
that makes you see life inside out!&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;In order to make the really big leaps like, for example, Einstein's
Relativity Theory, we need to be a bit crazy. It is impossible to
analytically reach certain conclusions. They can only be reached by
thinking so far outside the box, that most people would consider us
insane.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I will conclude with another quote from Leonard:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;It is easy to get on the path of mastery. The real challenge lies in
staying on it.&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-1237263625156985694?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/1237263625156985694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=1237263625156985694' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/1237263625156985694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/1237263625156985694'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/05/mastery.html' title='Mastery'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-vsjBDzXHvQo/TcZaL2EdtWI/AAAAAAAAAAU/W6s04Ke-3WY/s72-c/practice_curve.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-6651817509761918539</id><published>2011-04-05T10:44:00.004+02:00</published><updated>2011-04-05T14:30:39.510+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>What Is New in EcmaScript 5?</title><content type='html'>&lt;p&gt;More and more &lt;a href="http://kangax.github.com/es5-compat-table/"&gt;browsers have implemented EcmaScript
5&lt;/a&gt;. That means that it is
time to get up to speed on what it means for us as developers&lt;/p&gt;
&lt;p&gt;Here is a summary of Douglas Crockfords talk on Ecmascript 5 at
&lt;a href="http://www.scandevconf.se/2011/conference/speakers/douglas-crockford/"&gt;Scandev&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;New Syntax&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It is now possible to use reserved words as property names and in
unquoted literal keys.&lt;/li&gt;
&lt;li&gt;A comma is allowed after the last pair in object literals and after
the last element in array literals.&lt;/li&gt;
&lt;li&gt;It is possible to break strings by inserting a backslash at the end of
the line (not recommended by Doug).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;'please'&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
object &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;'down'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
array &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;'a'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'tapir'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'is'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'lovely'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;];&lt;/font&gt;
string &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;"a tapir is \&lt;/font&gt;
&lt;font color="#FF0000"&gt;beautiful"&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Library Additions&lt;/h2&gt;
&lt;h3&gt;JSON&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;JSON.parse&lt;/code&gt; and &lt;code&gt;JSON.stringify&lt;/code&gt; are now part of the standard.&lt;/p&gt;
&lt;h3&gt;Date&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Date&lt;/code&gt; has new methods, &lt;code&gt;toISOString&lt;/code&gt; and &lt;code&gt;toJSON&lt;/code&gt; It is also able to
parse ISO strings.&lt;/p&gt;
&lt;h3&gt;Object&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Object&lt;/code&gt; gets a bunch of new methods. But they are added on &lt;code&gt;Object&lt;/code&gt; and not
on &lt;code&gt;Object.prototype&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Creates an object with parent as prototype and properties from donor&lt;/font&gt;&lt;/i&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;create&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;parent&lt;font color="#990000"&gt;,&lt;/font&gt; donor&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Meta properties of an object&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; descriptor &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
value&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"test"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
writable&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;true&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// Can the value be changed?&lt;/font&gt;&lt;/i&gt;
enumerable&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;true&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// Will it appear in for-in and Object.keys(object)?&lt;/font&gt;&lt;/i&gt;
configurable&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;true&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// Can the property be removed?&lt;/font&gt;&lt;/i&gt;
set&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;value&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; test &lt;font color="#990000"&gt;=&lt;/font&gt; value&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// Getter&lt;/font&gt;&lt;/i&gt;
get&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; test &lt;font color="#FF0000"&gt;}&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// Setter&lt;/font&gt;&lt;/i&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Methods for manipulation the descriptors&lt;/font&gt;&lt;/i&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;defineProperty&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;,&lt;/font&gt; property&lt;font color="#990000"&gt;,&lt;/font&gt; descriptor&lt;font color="#990000"&gt;)&lt;/font&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;defineProperties&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;,&lt;/font&gt; descriptors&lt;font color="#990000"&gt;)&lt;/font&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;getOwnPropertyDescriptor&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;,&lt;/font&gt; property&lt;font color="#990000"&gt;)&lt;/font&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;getPrototypeOf&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Returns an array of enumerable properties&lt;/font&gt;&lt;/i&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;keys&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Returns an array of all properties&lt;/font&gt;&lt;/i&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;getOwnPropertyNames&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Prevents anyone from adding properties to the object, cannot be undone.&lt;/font&gt;&lt;/i&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;preventExtensions&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;isExtensible&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Prevents anyone from changing, properties or descriptors of the object.&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// The values can still be changed&lt;/font&gt;&lt;/i&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;seal&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
Objcect&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;isSealed&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Prevents any changes to the object.&lt;/font&gt;&lt;/i&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;freeze&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
Object&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;isFrozen&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;object&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h3&gt;Array&lt;/h3&gt;
&lt;p&gt;Arrays are extended with a bunch of new, useful methods, leading to less
need for third-party libraries.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Do all elements satisfy predicate?&lt;/font&gt;&lt;/i&gt;
Array&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;prototype&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;every&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;predicate&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Return a new array with the elements that satisfy predicate?&lt;/font&gt;&lt;/i&gt;
Array&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;prototype&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;filter&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;predicate&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Call action(element) for each element.&lt;/font&gt;&lt;/i&gt;
Array&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;prototype&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;forEach&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;action&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// What is the index of the first element that equals value?&lt;/font&gt;&lt;/i&gt;
Array&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;prototype&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;indexOf&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;value&lt;font color="#990000"&gt;,&lt;/font&gt; fromIndex&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// What is the index of the last element that equal value?&lt;/font&gt;&lt;/i&gt;
Array&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;prototype&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;lastIndexOf&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;value&lt;font color="#990000"&gt;,&lt;/font&gt; fromIndex&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Create a new array by applying unaryFunc to each element&lt;/font&gt;&lt;/i&gt;
Array&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;prototype&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;map&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;unaryFunc&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Reduces the elements of the array, by applying binaryFunc&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// between the elements&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// [a0, a1].reduce(+ , seed) == seed + a0 + a1&lt;/font&gt;&lt;/i&gt;
Array&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;prototype&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;reduce&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;binaryFunc&lt;font color="#990000"&gt;,&lt;/font&gt; seed&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// Is at least one element satisfied by the predicate?&lt;/font&gt;&lt;/i&gt;
Array&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;prototype&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;some&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;predicate&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h3&gt;String&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;String.prototype.trim&lt;/code&gt; is added to string. It trims whiespace from the
beginning and the end of a string.&lt;/p&gt;
&lt;h3&gt;Function&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Function.prototype.bind(thisArg, arg, ...)&lt;/code&gt; is added to function. It creates a new function by binding the value of this to a specified
object.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; tapir &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
method&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;name&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;{&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;name &lt;font color="#990000"&gt;=&lt;/font&gt; name&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt; tapir&lt;font color="#990000"&gt;.&lt;/font&gt;method&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;bind&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;tapir&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"Malayan"&lt;/font&gt;&lt;font color="#990000"&gt;),&lt;/font&gt; &lt;font color="#993399"&gt;100&lt;/font&gt; &lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Strict Mode&lt;/h2&gt;
&lt;p&gt;A new mode called strict can be turned on by writing&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
&lt;font color="#FF0000"&gt;"use strict"&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;It must be the first line in the function. It could also be the first
line of the file, but that does not play well with the optimizing
practices used in Javascript, like concatenation and minification.&lt;/p&gt;
&lt;p&gt;In strict mode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Variables must be declared before usage.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;with&lt;/code&gt; statement cannot be used.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eval&lt;/code&gt; is a reserved word.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;arguments.caller&lt;/code&gt; and &lt;code&gt;arguments.callee&lt;/code&gt; cannot be used.&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since IE6-IE9 does not implement strict model, Crockford thinks that
they "must die" since they, "hinder the creation of useful mashups".&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-sMuOcQTWxbQ/TZsLSQZgPDI/AAAAAAAAAAM/DHpYv-GRv-4/s1600/ie9mustdie.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/-sMuOcQTWxbQ/TZsLSQZgPDI/AAAAAAAAAAM/DHpYv-GRv-4/s320/ie9mustdie.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5592075770578091058" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-6651817509761918539?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/6651817509761918539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=6651817509761918539' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/6651817509761918539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/6651817509761918539'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/04/what-is-new-in-ecmascript-5.html' title='What Is New in EcmaScript 5?'/><author><name>Anders Janmyr</name><uri>http://www.blogger.com/profile/16081537018884349622</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-sMuOcQTWxbQ/TZsLSQZgPDI/AAAAAAAAAAM/DHpYv-GRv-4/s72-c/ie9mustdie.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-4504914762307137472</id><published>2011-03-28T20:43:00.001+02:00</published><updated>2011-03-28T20:52:18.120+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>High Performance Javascript</title><content type='html'>&lt;p&gt;Here are some tips on high perfomance Javascript I have picked up. Most
of it comes from the books &lt;a href="http://www.amazon.com/Performance-JavaScript-Faster-Application-Interfaces/dp/059680279X?tag=thtasta-20"&gt;High Performance Javascript&lt;/a&gt; 
by Nicholas C. Zakas and &lt;a href="http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309?tag=thtasta-20"&gt;High Performance Web Sites&lt;/a&gt; 
by Steve Souders.&lt;/p&gt; 
 
&lt;h2&gt;Loading&lt;/h2&gt; 
 
&lt;h3&gt;Load files at the end of the HTML page&lt;/h3&gt; 
 
&lt;p&gt;Load the Javascript files right before the body, this will allow the
page to render without having to wait for all the Javascript files.&lt;/p&gt; 
 
&lt;h3&gt;Group files together&lt;/h3&gt; 
 
&lt;p&gt;With normal loading, the files are loaded sequentially. Each file will
be loaded and parsed before the next file starts to load. Merge them
together into one large file. While you are at it, you should also
minimize it. Tools to help you with this are:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;&lt;a href="http://www.crockford.com/javascript/jsmin.html"&gt;JSMin&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;YUI Compressor&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h3&gt;Load files asynchronously&lt;/h3&gt; 
 
&lt;p&gt;If normal loading with grouped files is not good enough, it is also
possible to load the files asynchronously. This will also allow you to
load files on demand. Tools for this are:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;&lt;a href="http://github.com/rgrove/lazyload"&gt;LazyLoad&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://labjs.com/"&gt;LABjs&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://headjs.com/"&gt;HeadJS&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h2&gt;Variable Access&lt;/h2&gt; 
 
&lt;p&gt;Literal values and local variables can be accessed very quickly.  Array
access and member access take longer. If the &lt;em&gt;prototype chain&lt;/em&gt; or &lt;em&gt;scope
chain&lt;/em&gt; needs to be traversed, it will take longer the further up the chain
the access is. Global variables are always the slowest to access because
they are always last in the scope chain.&lt;/p&gt; 
 
&lt;p&gt;You can improve the performance of JavaScript code by storing frequently
used, object members, array items, and out-of-scope variables, in local
variables.&lt;/p&gt; 
 
&lt;h2&gt;DOM&lt;/h2&gt; 
 
&lt;p&gt;&lt;em&gt;All DOM manipulation is slow.&lt;/em&gt;&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Minimize DOM access&lt;/li&gt; 
&lt;li&gt;Use local variables to store DOM references you'll access repeatedly.&lt;/li&gt; 
&lt;li&gt;HTML collections represent the live, underlying document, so:
 
&lt;ul&gt; 
&lt;li&gt;Cache the collection length into a variable and use it when iterating&lt;/li&gt; 
&lt;li&gt;Make a copy of the collection into an array for heavy work on collections&lt;/li&gt; 
&lt;/ul&gt; 
&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h3&gt;Reflow and rendering&lt;/h3&gt; 
 
&lt;p&gt;The browser contains two trees, the &lt;em&gt;DOM tree&lt;/em&gt; and a &lt;em&gt;render tree&lt;/em&gt;.
Whenever the DOM layout or geometry is changed the view will have to be
re-rendered. This is known as reflow.&lt;/p&gt; 
 
&lt;p&gt;Reflow happens when:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Visible DOM elements are added or removed&lt;/li&gt; 
&lt;li&gt;Elements change position&lt;/li&gt; 
&lt;li&gt;Elements change size (margin, padding, border thickness, width, height, etc.)&lt;/li&gt; 
&lt;li&gt;Content is changed, (text changes or an image is replaced with one of a different size)&lt;/li&gt; 
&lt;li&gt;The page renders initially&lt;/li&gt; 
&lt;li&gt;The browser window is resized&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;p&gt;Combine multiple DOM and style changes into a batch and apply them once.
This can be done with documentFragments or by cloning the node.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Create a document fragment&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; fragment &lt;font color="#990000"&gt;=&lt;/font&gt; document&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;createDocumentFragment&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Do something with framgment&lt;/font&gt;&lt;/i&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Append the fragments children to the DOM&lt;/font&gt;&lt;/i&gt; 
document&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;getElementById&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'mylist'&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;appendChild&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;fragment&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Clone Node&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; old &lt;font color="#990000"&gt;=&lt;/font&gt; document&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;getElementById&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'mylist'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; clone &lt;font color="#990000"&gt;=&lt;/font&gt; old&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;cloneNode&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;true&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Do something with clone&lt;/font&gt;&lt;/i&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Replace node with clone&lt;/font&gt;&lt;/i&gt; 
old&lt;font color="#990000"&gt;.&lt;/font&gt;parentNode&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;replaceChild&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;clone&lt;font color="#990000"&gt;,&lt;/font&gt; old&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h2&gt;Algorithms and Flow&lt;/h2&gt; 
 
&lt;p&gt;Use algortithms with better complexity performance for large collections.&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;&lt;em&gt;for-in&lt;/em&gt; loops are slower than for, while and do-while loops. Avoid
for-in unless you need to iterate over a number of unknown object
properties.&lt;/li&gt; 
&lt;li&gt;Lookup-tables are faster than multiple conditionals.&lt;/li&gt; 
&lt;li&gt;Recursion can be re-written with iteration if you get stackoverflow
errors.&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h2&gt;Strings and Regexes&lt;/h2&gt; 
 
&lt;p&gt;Strings concatenation is quite fast in most browsers. In IE, you may
need to use &lt;em&gt;Array.join&lt;/em&gt;.&lt;/p&gt; 
 
&lt;p&gt;Regular expression can be improved by:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Focus on failing faster.&lt;/li&gt; 
&lt;li&gt;Start regexes with simple, required tokens.&lt;/li&gt; 
&lt;li&gt;Make quantified patterns and their following pattern mutually exclusive /"[&amp;#94;"]*"/.&lt;/li&gt; 
&lt;li&gt;Use noncapturing groups. (?:) instead of ().&lt;/li&gt; 
&lt;li&gt;Capture text to reduce postprocessing.&lt;/li&gt; 
&lt;li&gt;Expose required tokens /&amp;#94;(ab|cd)/ instead of /(&amp;#94;ab|&amp;#94;cd)&lt;/li&gt; 
&lt;li&gt;Resue regexes by assigning them to variables.&lt;/li&gt; 
&lt;li&gt;Split complex regexes into simpler pieces.&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h2&gt;Responsiveness&lt;/h2&gt; 
 
&lt;p&gt;The total amount of time that a single JavaScript operation should take
is 100. If it takes longer it needs to be split up, this can be done
using timers.&lt;/p&gt; 
 
&lt;p&gt;Two determining factors for whether a loop can be done asynchronously
using timers:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Does the processing have to be done synchronously?&lt;/li&gt; 
&lt;li&gt;Does the data have to be processed sequentially?&lt;/li&gt; 
&lt;/ul&gt; 
 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Function for processing an array in parallel&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;processArray&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;items&lt;font color="#990000"&gt;,&lt;/font&gt; process&lt;font color="#990000"&gt;,&lt;/font&gt; callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; minTimeToStart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;25&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; copyOfItems &lt;font color="#990000"&gt;=&lt;/font&gt; items&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;concat&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#000000"&gt;process&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;copyOfItems&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;shift&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;());&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;copyOfItems&lt;font color="#990000"&gt;.&lt;/font&gt;lengthÂ &lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;arguments&lt;font color="#990000"&gt;.&lt;/font&gt;callee&lt;font color="#990000"&gt;,&lt;/font&gt; minTimeToStart&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt; 
      &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;items&lt;font color="#990000"&gt;);&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; minTimeToStart&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Function for processing multiple tasks in parallel&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;processTasks&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;tasks&lt;font color="#990000"&gt;,&lt;/font&gt; args&lt;font color="#990000"&gt;,&lt;/font&gt; callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; minTimeToStart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;25&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; copyOfTasks &lt;font color="#990000"&gt;=&lt;/font&gt; steps&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;concat&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; task &lt;font color="#990000"&gt;=&lt;/font&gt; copyOfTasks&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;shift&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
    task&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;apply&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;null&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; args &lt;font color="#990000"&gt;||&lt;/font&gt; &lt;font color="#990000"&gt;[]);&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;copyOfTasks&lt;font color="#990000"&gt;.&lt;/font&gt;length &lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;arguments&lt;font color="#990000"&gt;.&lt;/font&gt;callee&lt;font color="#990000"&gt;,&lt;/font&gt; minTimeToStart&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt; 
      &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; minTimeToStart&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;You should limit the number of high-frequency repeating timers in your
web application. It is better to create a single repeating timer that
performs multiple operations with each execution.&lt;/p&gt; 
 
&lt;p&gt;It is not recommended to have &lt;em&gt;minTimeToStart&lt;/em&gt; less than 25
milliseconds, because there is a risk that the timers will fill up the
queue.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Timed version of process array, where each version is able to&lt;/font&gt;&lt;/i&gt; 
&lt;i&gt;&lt;font color="#9A1900"&gt;// process items from the array for up to 50 milliseconds.&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;timedProcessArray&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;items&lt;font color="#990000"&gt;,&lt;/font&gt; process&lt;font color="#990000"&gt;,&lt;/font&gt; callback&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; minTimeToStart &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;25&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; copyOfItems &lt;font color="#990000"&gt;=&lt;/font&gt; items&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;concat&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
    &lt;i&gt;&lt;font color="#9A1900"&gt;// (+) converts the Date object into a numeric representation&lt;/font&gt;&lt;/i&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; start &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Date&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#000000"&gt;process&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;copyOfItems&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;shift&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;());&lt;/font&gt; 
    &lt;font color="#FF0000"&gt;}&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;while&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;copyOfItems&lt;font color="#990000"&gt;.&lt;/font&gt;length &lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt; &lt;font color="#990000"&gt;&amp;amp;&amp;amp;&lt;/font&gt; &lt;font color="#990000"&gt;(+&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Date&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt; start &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; &lt;font color="#993399"&gt;50&lt;/font&gt;&lt;font color="#990000"&gt;));&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;copyOfItems&lt;font color="#990000"&gt;.&lt;/font&gt;length &lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#000000"&gt;setTimeout&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;arguments&lt;font color="#990000"&gt;.&lt;/font&gt;callee&lt;font color="#990000"&gt;,&lt;/font&gt; minTimeToStart&lt;font color="#990000"&gt;);&lt;/font&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt; 
      &lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;items&lt;font color="#990000"&gt;)&lt;/font&gt; 
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; minTimeToStart&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Newer browsers support web workers. Web workers does not run in the
UI-thread and does not affect responsiveness at all. Their environment
is limited to allow this to work. It is limited to:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;A navigator object, which contains only four properties: appName,
appVersion, user Agent, and platform.&lt;/li&gt; 
&lt;li&gt;A location object (same as on window, except all properties are read-only)&lt;/li&gt; 
&lt;li&gt;A self object that points to the global worker object&lt;/li&gt; 
&lt;li&gt;An importScripts() method that is used to load external JavaScript for
use in the worker&lt;/li&gt; 
&lt;li&gt;All ECMAScript objects, such as Object, Array, Date, etc.&lt;/li&gt; 
&lt;li&gt;The XMLHttpRequest constructor&lt;/li&gt; 
&lt;li&gt;The setTimeout() and setInterval() methods&lt;/li&gt; 
&lt;li&gt;A close() method that stops the worker immediately&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;p&gt;It is not possible to create a &lt;em&gt;WebWorker&lt;/em&gt; from code. It needs to be
started with its own javascript file. You can however communicate with
it through events.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Application code&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; worker &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Worker&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"code.js"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
worker&lt;font color="#990000"&gt;.&lt;/font&gt;onmessage &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;event&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#000000"&gt;alert&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;event&lt;font color="#990000"&gt;.&lt;/font&gt;data&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
worker&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;postMessage&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"Tapir"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
 
&lt;i&gt;&lt;font color="#9A1900"&gt;// Worker code (code.js)&lt;/font&gt;&lt;/i&gt; 
&lt;i&gt;&lt;font color="#9A1900"&gt;//inside code.js&lt;/font&gt;&lt;/i&gt; 
&lt;b&gt;&lt;font color="#000000"&gt;importScripts&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"file1.js"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"file2.js"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;// importing some files&lt;/font&gt;&lt;/i&gt; 
 
self&lt;font color="#990000"&gt;.&lt;/font&gt;onmessage &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;event&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
  self&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;postMessage&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"Hello, "&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; event&lt;font color="#990000"&gt;.&lt;/font&gt;data &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;font color="#FF0000"&gt;"!"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt; 
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Any code that takes longer than 100 milliseconds to run should be
refactored to use webworkers to decrease the load on the UI-thread.&lt;/p&gt; 
 
&lt;h2&gt;Ajax&lt;/h2&gt; 
 
&lt;p&gt;Favor lightweight formats in general; the best is JSON and
a character-delimited custom format. If the data set is large and parse
time becomes an issue, use one of these two techniques:&lt;/p&gt; 
 
&lt;p&gt;JSON-P data, fetched using dynamic script tag insertion. This treats the
data as executable JavaScript, not a string, and allows for extremely
fast parsing. This can be used across domains, but shouldn't be used
with sensitive data.&lt;/p&gt; 
 
&lt;p&gt;A character-delimited custom format, fetched using either XHR or dynamic
script tag insertion and parsed using &lt;code&gt;split()&lt;/code&gt;. This technique parses
extremely large datasets slightly faster than the JSON-P technique, and
generally has a smaller file size.&lt;/p&gt; 
 
&lt;p&gt;&lt;em&gt;XML has no place in high-performance Ajax.&lt;/em&gt;&lt;/p&gt; 
 
&lt;p&gt;Cache data! The fastest Ajax request is one that you don't have to make.
There are two main ways of preventing an unnecessary request:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;On the server side, set HTTP headers that ensure your response will be
cached in the browser.&lt;/li&gt; 
&lt;li&gt;On the client side, store fetched data locally so that it doesn't have
be requested again.&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;p&gt;Multipart XHR can be used to reduce the number of requests, and can
handle different file types in a single response, though it does not
cache the resources received.&lt;/p&gt; 
 
&lt;p&gt;Some more guidelines that will help your Ajax appear to be faster:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Reduce the number of requests you make, either by concatenating
JavaScript and CSS files, or by using MXHR.&lt;/li&gt; 
&lt;li&gt;Improve the perceived loading time of your page by using Ajax to fetch
less important files after the rest of the page has loaded.&lt;/li&gt; 
&lt;li&gt;Ensure your code fails gracefully and can handle problems on the
server side.&lt;/li&gt; 
&lt;li&gt;Know when to use a robust Ajax library and when to write your own
low-level Ajax code.&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h2&gt;Programming Practices&lt;/h2&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Avoid the use of eval() and the Function() constructor.&lt;/li&gt; 
&lt;li&gt;Pass functions into setTimeout() and setInterval() instead of strings.&lt;/li&gt; 
&lt;li&gt;Use object and array literals when creating new objects and arrays.&lt;/li&gt; 
&lt;li&gt;Avoid doing the same work repeatedly.&lt;/li&gt; 
&lt;li&gt;Use lazy loading or conditional advance loading when browser-detection
logic is necessary.&lt;/li&gt; 
&lt;li&gt;When performing mathematical operations, consider using bitwise
operators that work directly on the underlying representation of the
number.&lt;/li&gt; 
&lt;li&gt;Native methods are always faster than anything you can write in
JavaScript.&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h2&gt;Building and Deploying&lt;/h2&gt; 
 
&lt;p&gt;The build and deployment process can have a tremendous impact on the
performance of a JavaScript-based application. The most important steps
in this process are:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Combining JavaScript files to reduce the number of HTTP requests&lt;/li&gt; 
&lt;li&gt;Minifying JavaScript files using the YUI Compressor&lt;/li&gt; 
&lt;li&gt;Serving JavaScript files compressed (gzip encoding)&lt;/li&gt; 
&lt;li&gt;Making JavaScript files cacheable by setting the appropriate HTTP
response headers&lt;/li&gt; 
&lt;li&gt;Work around caching issues by appending a timestamp to filenames&lt;/li&gt; 
&lt;li&gt;Using a Content Delivery Network to serve JavaScript files;&lt;/li&gt; 
&lt;li&gt;All these steps should be automated using build tools&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h2&gt;Tools&lt;/h2&gt; 
 
&lt;h3&gt;Minification&lt;/h3&gt; 
 
&lt;ul&gt; 
&lt;li&gt;The &lt;a href="http://code.google.com/closure/compiler/"&gt;Google Closure Compiler&lt;/a&gt;.&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://github.com/jlecomte/smasher"&gt;Smasher&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://www.crockford.com/javascript/jsmin.html"&gt;JSMin&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;YUI Compressor&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h3&gt;Profiling&lt;/h3&gt; 
 
&lt;ul&gt; 
&lt;li&gt;The &lt;a href="http://developer.yahoo.com/yui/profiler/"&gt;YUI Profiler&lt;/a&gt;,&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://code.google.com/speed/page-speed/"&gt;Page Speed&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://ajax.dynatrace.com/pages/"&gt;dynaTrace Ajax Edition&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h3&gt;Development&lt;/h3&gt; 
 
&lt;ul&gt; 
&lt;li&gt;&lt;a href="http://www.getfirebug.com/"&gt;Firebug&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;Internet Explorer Developer Tools&lt;/li&gt; 
&lt;li&gt;Safari Web Inspector&lt;/li&gt; 
&lt;li&gt;Chrome Developer Tools&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h3&gt;Proxies&lt;/h3&gt; 
 
&lt;ul&gt; 
&lt;li&gt;&lt;a href="http://www.fiddler2.com/fiddler2/"&gt;Fiddler&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href="http://www.charlesproxy.com/"&gt;Charles Proxy&lt;/a&gt;&lt;/li&gt; 
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-4504914762307137472?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/4504914762307137472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=4504914762307137472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4504914762307137472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4504914762307137472'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/03/high-performance-javascript.html' title='High Performance Javascript'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-2174367933610415079</id><published>2011-03-01T20:54:00.000+01:00</published><updated>2011-03-01T20:54:42.742+01:00</updated><title type='text'>Host Specific Routing Via the iPhone on OSX</title><content type='html'>&lt;p&gt;If you are working as a consultant, it is sometimes not easy to get
proper network access when you are using your customer's network. The
easiest way to solve this problem is to connect via your mobile phone.
But, the 3G network is not always the fastest and it would be nice to
use the normal network for certain tasks and the 3G network for others.&lt;/p&gt; 
 
&lt;p&gt;The problem in my case was that I wanted to connect to Github but, SSH
traffic was blocked on the network where I was working. So what to do?
I quick mail to the Jayway tech mailing list, lets me know that in Linux
there is a &lt;code&gt;route&lt;/code&gt; command, that can solve this problem. (Un)Fortunately
I am not using Linux on my development machine, but it turns out there
is a &lt;code&gt;route(8)&lt;/code&gt; command in BSD too, with slightly different syntax.&lt;/p&gt; 
 
&lt;h3&gt;Find the IP-address of the host I wish to connect to&lt;/h3&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Find the IP-address of the host I wish to connect to&lt;/font&gt;&lt;/i&gt; 
$ nslookup github&lt;font color="#990000"&gt;.&lt;/font&gt;com
Server&lt;font color="#990000"&gt;:&lt;/font&gt;  &lt;font color="#993399"&gt;195.58&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;103.21&lt;/font&gt; 
Address&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;195.58&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;103.21&lt;/font&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;#53&lt;/font&gt;&lt;/i&gt; 
 
Non-authoritative answer&lt;font color="#990000"&gt;:&lt;/font&gt; 
Name&lt;font color="#990000"&gt;:&lt;/font&gt; github&lt;font color="#990000"&gt;.&lt;/font&gt;com
Address&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#993399"&gt;207.97&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;227.239&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;h3&gt;Find out the gateway of the interface of the cell phone&lt;/h3&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Find out the gateway of the interface of the cell phone&lt;/font&gt;&lt;/i&gt; 
$ ifconfig
lo0&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#009900"&gt;flags&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#993399"&gt;8049&lt;/font&gt;&lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;UP&lt;font color="#990000"&gt;,&lt;/font&gt;LOOPBACK&lt;font color="#990000"&gt;,&lt;/font&gt;RUNNING&lt;font color="#990000"&gt;,&lt;/font&gt;MULTICAST&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; mtu &lt;font color="#993399"&gt;16384&lt;/font&gt; 
 inet &lt;font color="#993399"&gt;127.0&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;0.1&lt;/font&gt; netmask &lt;font color="#993399"&gt;0xff000000&lt;/font&gt; 
 inet6 &lt;font color="#990000"&gt;::&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt; prefixlen &lt;font color="#993399"&gt;128&lt;/font&gt; 
 inet6 fe80&lt;font color="#990000"&gt;::&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;%&lt;/font&gt;lo0 prefixlen &lt;font color="#993399"&gt;64&lt;/font&gt; scopeid &lt;font color="#993399"&gt;0x1&lt;/font&gt; 
&lt;font color="#990000"&gt;...&lt;/font&gt; 
vmnet8&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#009900"&gt;flags&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#993399"&gt;8863&lt;/font&gt;&lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;UP&lt;font color="#990000"&gt;,&lt;/font&gt;BROADCAST&lt;font color="#990000"&gt;,&lt;/font&gt;SMART&lt;font color="#990000"&gt;,&lt;/font&gt;RUNNING&lt;font color="#990000"&gt;,&lt;/font&gt;SIMPLEX&lt;font color="#990000"&gt;,&lt;/font&gt;MULTICAST&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; mtu &lt;font color="#993399"&gt;1500&lt;/font&gt; 
 ether &lt;font color="#993399"&gt;00&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;50&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;56&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;c0&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;00&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;08&lt;/font&gt; 
 inet &lt;font color="#993399"&gt;192.168&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;105.1&lt;/font&gt; netmask &lt;font color="#993399"&gt;0xffffff00&lt;/font&gt; broadcast &lt;font color="#993399"&gt;192.168&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;105.255&lt;/font&gt; 
en3&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#009900"&gt;flags&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#993399"&gt;8863&lt;/font&gt;&lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;UP&lt;font color="#990000"&gt;,&lt;/font&gt;BROADCAST&lt;font color="#990000"&gt;,&lt;/font&gt;SMART&lt;font color="#990000"&gt;,&lt;/font&gt;RUNNING&lt;font color="#990000"&gt;,&lt;/font&gt;SIMPLEX&lt;font color="#990000"&gt;,&lt;/font&gt;MULTICAST&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; mtu &lt;font color="#993399"&gt;1500&lt;/font&gt; 
 ether &lt;font color="#993399"&gt;06&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;1e&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;64&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;00&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;34&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;1a 
 inet6 fe80&lt;font color="#990000"&gt;::&lt;/font&gt;41e&lt;font color="#990000"&gt;:&lt;/font&gt;64ff&lt;font color="#990000"&gt;:&lt;/font&gt;fe00&lt;font color="#990000"&gt;:&lt;/font&gt;341a&lt;font color="#990000"&gt;%&lt;/font&gt;en3 prefixlen &lt;font color="#993399"&gt;64&lt;/font&gt; scopeid &lt;font color="#993399"&gt;0xa&lt;/font&gt; 
 inet &lt;font color="#993399"&gt;172.20&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.3&lt;/font&gt; netmask &lt;font color="#993399"&gt;0xfffffff0&lt;/font&gt; broadcast &lt;font color="#993399"&gt;172.20&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.15&lt;/font&gt; 
 media&lt;font color="#990000"&gt;:&lt;/font&gt; 10baseT/UTP
 status&lt;font color="#990000"&gt;:&lt;/font&gt; active
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;In my case the interface I want to use is the last one, &lt;strong&gt;en3&lt;/strong&gt; with &lt;strong&gt;inet
172.20.10.3&lt;/strong&gt; but if you are unsure, you can open the network preference
pane and look it up there.&lt;/p&gt; 
 
&lt;p&gt;Now I need to find out what the gateway for this interface is. I can
do this with &lt;code&gt;netstat -r&lt;/code&gt;.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Show the routing table&lt;/font&gt;&lt;/i&gt; 
$ netstat -r
Routing tables
 
Internet&lt;font color="#990000"&gt;:&lt;/font&gt; 
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            &lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.254&lt;/font&gt;       UGSc           &lt;font color="#993399"&gt;10&lt;/font&gt;        &lt;font color="#993399"&gt;0&lt;/font&gt;     en1
default            &lt;font color="#993399"&gt;172.20&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.1&lt;/font&gt;        UGScI           &lt;font color="#993399"&gt;0&lt;/font&gt;        &lt;font color="#993399"&gt;0&lt;/font&gt;     en3
&lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;24&lt;/font&gt;        link&lt;i&gt;&lt;font color="#9A1900"&gt;#5             UCS             3        0     en1&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.88&lt;/font&gt;        localhost          UHS             &lt;font color="#993399"&gt;1&lt;/font&gt;      &lt;font color="#993399"&gt;811&lt;/font&gt;     lo0
&lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.254&lt;/font&gt;       &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;14&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;4f&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;69&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;da&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;13&lt;/font&gt;   UHLWI          &lt;font color="#993399"&gt;10&lt;/font&gt;       &lt;font color="#993399"&gt;41&lt;/font&gt;     en1    &lt;font color="#993399"&gt;661&lt;/font&gt; 
&lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.255&lt;/font&gt;       link&lt;i&gt;&lt;font color="#9A1900"&gt;#5             UHLWbI          1       78     en1&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#993399"&gt;127&lt;/font&gt;                localhost          UCS             &lt;font color="#993399"&gt;0&lt;/font&gt;        &lt;font color="#993399"&gt;0&lt;/font&gt;     lo0
&lt;font color="#990000"&gt;...&lt;/font&gt; 
 
Internet6&lt;font color="#990000"&gt;:&lt;/font&gt; 
Destination        Gateway            Flags         Netif Expire
localhost          localhost          UH              lo0
fe80&lt;font color="#990000"&gt;::%&lt;/font&gt;lo0         localhost          Uc              lo0
localhost          link&lt;i&gt;&lt;font color="#9A1900"&gt;#1             UHL             lo0&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#990000"&gt;...&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Close to the top we find the entry for our interface &lt;strong&gt;en3&lt;/strong&gt;.&lt;/p&gt; 
 
&lt;pre&gt;&lt;code&gt;default            172.20.10.1        UGScI           0        0     en3
&lt;/code&gt;&lt;/pre&gt; 
 
&lt;p&gt;Now we have the ip to the gateway that we wanted. So now the last step
is to make sure that access to github.com is routed via this gateway.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;#route command -host destination gateway&lt;/font&gt;&lt;/i&gt; 
$ sudo route add -host &lt;font color="#993399"&gt;207.97&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;227.239&lt;/font&gt; &lt;font color="#993399"&gt;172.20&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.1&lt;/font&gt; 
add host &lt;font color="#993399"&gt;207.97&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;227.239&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt; gateway &lt;font color="#993399"&gt;172.20&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.1&lt;/font&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;That's it, I'm done. To make sure the routing is changed I check the
routing table with &lt;code&gt;netstat -r&lt;/code&gt; again, to make sure the new entry is in it.&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ netstat -r
Routing tables
 
Internet&lt;font color="#990000"&gt;:&lt;/font&gt; 
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            &lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.254&lt;/font&gt;       UGSc           &lt;font color="#993399"&gt;30&lt;/font&gt;        &lt;font color="#993399"&gt;0&lt;/font&gt;     en1
default            &lt;font color="#993399"&gt;172.20&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.1&lt;/font&gt;        UGScI           &lt;font color="#993399"&gt;0&lt;/font&gt;        &lt;font color="#993399"&gt;0&lt;/font&gt;     en3
&lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;24&lt;/font&gt;        link&lt;i&gt;&lt;font color="#9A1900"&gt;#5             UCS             4        0     en1&lt;/font&gt;&lt;/i&gt; 
&lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.88&lt;/font&gt;        localhost          UHS             &lt;font color="#993399"&gt;0&lt;/font&gt;      &lt;font color="#993399"&gt;973&lt;/font&gt;     lo0
&lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.254&lt;/font&gt;       &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;14&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;4f&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;69&lt;/font&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;da&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;font color="#993399"&gt;13&lt;/font&gt;   UHLWI          &lt;font color="#993399"&gt;27&lt;/font&gt;       &lt;font color="#993399"&gt;11&lt;/font&gt;     en1    &lt;font color="#993399"&gt;708&lt;/font&gt; 
&lt;font color="#993399"&gt;10.67&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.255&lt;/font&gt;       ff&lt;font color="#990000"&gt;:&lt;/font&gt;ff&lt;font color="#990000"&gt;:&lt;/font&gt;ff&lt;font color="#990000"&gt;:&lt;/font&gt;ff&lt;font color="#990000"&gt;:&lt;/font&gt;ff&lt;font color="#990000"&gt;:&lt;/font&gt;ff  UHLWbI          &lt;font color="#993399"&gt;1&lt;/font&gt;       &lt;font color="#993399"&gt;14&lt;/font&gt;     en1
&lt;font color="#993399"&gt;127&lt;/font&gt;                localhost          UCS             &lt;font color="#993399"&gt;0&lt;/font&gt;        &lt;font color="#993399"&gt;0&lt;/font&gt;     lo0
&lt;font color="#990000"&gt;...&lt;/font&gt; 
github&lt;font color="#990000"&gt;.&lt;/font&gt;com         &lt;font color="#993399"&gt;172.20&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.1&lt;/font&gt;        UGHS            &lt;font color="#993399"&gt;0&lt;/font&gt;       &lt;font color="#993399"&gt;43&lt;/font&gt;     en3
 
Internet6&lt;font color="#990000"&gt;:&lt;/font&gt; 
Destination        Gateway            Flags         Netif Expire
localhost          localhost          UH              lo0
fe80&lt;font color="#990000"&gt;::%&lt;/font&gt;lo0         localhost          Uc              lo0
localhost          link&lt;i&gt;&lt;font color="#9A1900"&gt;#1             UHL             lo0&lt;/font&gt;&lt;/i&gt; 
fe80&lt;font color="#990000"&gt;::%&lt;/font&gt;en0         link&lt;i&gt;&lt;font color="#9A1900"&gt;#4             UC              en0&lt;/font&gt;&lt;/i&gt; 
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;Sure enough, there it is, &lt;code&gt;github.com&lt;/code&gt;. Finally I can now &lt;code&gt;git pull&lt;/code&gt; 
and everything works :).&lt;/p&gt; 
 
&lt;p&gt;If I want to remove the entry, when I'm working elsewhere, I do that with&lt;/p&gt; 
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt; 
$ sudo route delete -host &lt;font color="#993399"&gt;207.97&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;227.239&lt;/font&gt; &lt;font color="#993399"&gt;172.20&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#993399"&gt;10.1&lt;/font&gt; 
 
 
  
 
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-2174367933610415079?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/2174367933610415079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=2174367933610415079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2174367933610415079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2174367933610415079'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/03/host-specific-routing-via-iphone-on-osx.html' title='Host Specific Routing Via the iPhone on OSX'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-894370584001793852</id><published>2011-02-26T15:55:00.001+01:00</published><updated>2011-02-28T09:42:14.569+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='methods'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Continuous Delivery</title><content type='html'>&lt;p&gt;I just finished the book, &lt;a href="http://www.amazon.com/gp/product/0321601912?tag=thtasta-20"&gt;Continuous
Delivery&lt;/a&gt; by Jez
Humble and David Farley. It's a great book, but it is a bit wordy (512 pages),
so here is the gist of it.&lt;/p&gt; 
 
&lt;p&gt;Continuous delivery builds on a simple foundation, continuous integration,
automation, and version control. But in order to get it to work you must
version control and automate everything. It's that simple! &lt;em&gt;Version control and
automate everything!&lt;/em&gt; Everything means different things to different people,
but to Jez and David it means &lt;em&gt;a lot&lt;/em&gt;.&lt;/p&gt; 
 
&lt;p&gt;You should version control:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Source code and test code&lt;/li&gt; 
&lt;li&gt;Assets, images, media files, base data, etc.&lt;/li&gt; 
&lt;li&gt;Build scripts&lt;/li&gt; 
&lt;li&gt;Deployment scripts&lt;/li&gt; 
&lt;li&gt;Secret configuration settings, like keys and passwords&lt;/li&gt; 
&lt;li&gt;Environments, development, production, test, staging, ...&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;p&gt;The first three you are hopefully doing already, but the fourth is unusual
and the fifth and sixth, I rarely see anywhere. Secret settings should be kept
in version control too, just don't put them into the public repository. Here
are some question to ask yourself:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Can you set up a complete development machine with one command?&lt;/li&gt; 
&lt;li&gt;Can you set up the deployment pipeline machine with one command?&lt;/li&gt; 
&lt;li&gt;Can you set up a fresh test environment with one command?&lt;/li&gt; 
&lt;li&gt;Can you set up a complete production environment with one command?&lt;/li&gt; 
&lt;li&gt;Can you upgrade the application, including data migrations, with one command?&lt;/li&gt; 
&lt;li&gt;Can you roll it back, in case it fails, with one command?&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;h2&gt;The Deployment Pipeline&lt;/h2&gt; 
 
&lt;p&gt;Continuous Delivery uses a Continuous Itegration server to drive the
&lt;em&gt;Deployment Pipeline&lt;/em&gt;. In the simplest form of application, a deployment
pipeline may have only one step. This step, runs all the tests and if all goes
well it will deploy the application. But as soon as the application grows this
will take too long, the single step needs to become a pipeline.&lt;/p&gt; 
 
&lt;p&gt;A deployment pipeline may have arbitrary many steps and they should be as
automated as possible. A common setup of a deployment pipeline contains the
following steps.&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;The Commit Stage (automatic)&lt;/li&gt; 
&lt;li&gt;The Integration Test Stage (automatic)&lt;/li&gt; 
&lt;li&gt;The Acceptance Test Stage (automatic)&lt;/li&gt; 
&lt;li&gt;Exploratory Testing Stage (manual)&lt;/li&gt; 
&lt;li&gt;Perfomance Testing Stage (automatic)&lt;/li&gt; 
&lt;li&gt;Deployment Stage (triggered manually)&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;p&gt;The main reason for the deployment pipeline is to provide feedback as
fast as possible. The commit stage typically only contains unit tests
that run very fast. The steps after that only run if the step before
succeeds.&lt;/p&gt; 
 
&lt;p&gt;The steps above may contain everything you need, too much, or in the
wrong order.  Feel free to remove and re-order as you please. If
performance testing is cheaper than exploratory testing, in your case,
switch them.  There is no one-solution-fits-all when it comes to
pipelines. Customize it, to fit your needs.&lt;/p&gt; 
 
&lt;p&gt;One important aspect of the deployment pipeline that I rarely see is that the
final product should be created by the first commit stage and then resused by
the other stages. Very often I see that the separate stages check out and
build a new version from scratch, albeit a tagged version but still. The reuse
of the same artifact through all the steps not only ensures that the same
artifact has passed all the stages, it also speeds up the deployment pipeline,
removing redundant work.&lt;/p&gt; 
 
&lt;p&gt;Another thing worth noting is that the manual steps described above should be
as automatic as possible. If a tester want to test the latest build that has
passed the acceptance test stage, he should be able to do it with one click.
That one click may involve:&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Create a fresh production like environment.&lt;/li&gt; 
&lt;li&gt;Install the selected artifact into the new envrionment.&lt;/li&gt; 
&lt;li&gt;Apply all the relevant configuration.&lt;/li&gt; 
&lt;/ul&gt; 
 
 
&lt;p&gt;If the tester decides that the build should fail or succeed, he should be able
to do that with one click. And, the feedback with the result should be fed back
into the deploynment cycle so that the developers know that it failed, and why,
or the operation guys knows that there is a new version ready to deploy.&lt;/p&gt; 
 
&lt;h2&gt;Conclusion&lt;/h2&gt; 
 
&lt;p&gt;The book is a good read and I highly recommend it. In the process of describing
continuous delivery, it provides tons of useful tips on keeping your
code and data under control. Among other things it describes.&lt;/p&gt; 
 
&lt;ul&gt; 
&lt;li&gt;Release strategies, such as canary relasing and blue-green deployment.&lt;/li&gt; 
&lt;li&gt;Test strategies for acceptance tests, capacity test, etc.&lt;/li&gt; 
&lt;li&gt;Why not to use long-lived feature branches and how to avoid it.&lt;/li&gt; 
&lt;li&gt;Dependency management&lt;/li&gt; 
&lt;li&gt;...&lt;/li&gt; 
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-894370584001793852?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/894370584001793852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=894370584001793852' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/894370584001793852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/894370584001793852'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/02/continuous-delivery.html' title='Continuous Delivery'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-2019417748752156863</id><published>2011-01-09T21:50:00.001+01:00</published><updated>2011-01-09T21:54:08.295+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic'/><title type='text'>Dynamic For The Win</title><content type='html'>&lt;blockquote&gt;&lt;p&gt;Everything passes, everything. -- Anthony de Mello, Awareness&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Take a look at what is happening around you. Relational databases are replaced by NoSQL databases. SOAP is replaced by REST, Javascript is dominating web development. The only place where dynamic is not winning is in the world of programming languages. But even if you take a look at programming languages, you can see that many of the largest most vital sites, such as Facebook and Wikipedia, are using dynamic languages. Why?&lt;/p&gt;

&lt;h2&gt;Dynamic is Better&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt; It's not the strongest of the species that survives, nor the most intelligent, but those who are most responsive to change. -- Charles Darwin&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;What I mean when I say that dynamic is better is that dynamic systems are more responsive to change. And change, as they say, is the only thing that we can be sure of!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If I need to add a new field to a NoSQL database, I just do it.&lt;/li&gt;
&lt;li&gt;If I need to add new field to my RESTful web service, I just do it.&lt;/li&gt;
&lt;li&gt;If I need to alter the behavior of my Javascript UI, I change it, reload the page, done!&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Soap vs. REST&lt;/h3&gt;

&lt;p&gt;REST is beating the hell out of SOAP nowadays, but you may have noticed that most "RESTful" web services aren't really RESTful. They don't follow the HATEOAS rule, they are just "Accessible over HTTP". So why the big fuss about "REST" if no one is using it as intended?  Because there are no contracts for REST! You are not constrained by WSDL and all the other bloated specifications. You can just publish your services without contracts, write some documentation and be done with it.&lt;/p&gt;

&lt;h3&gt;Relational vs. NoSQL Databases&lt;/h3&gt;

&lt;p&gt;NoSQL is the new rave, and most people think that it is because they allow us to handle large amounts of data, fast. I don't think that is the main reason. I think the main reason is that they are schemaless. It is easy to add or remove fields without changing the data of all the other items of similar type. The problem with relational databases is not, in most cases, that they are slow, it is that they have a rigid contract that make them painful to work with. This effect is also, often, amplified by having O/R-mappers wrap the tables in static types.&lt;/p&gt;

&lt;h3&gt;Javascript vs. RIA Plugins&lt;/h3&gt;

&lt;p&gt;Javascript is the clear winner as the programming language of the web. Silverlight finally threw in the towel and Java is only living in ancient bank applets. Javascript is one of the most dynamic languages that you can imagine and it has won the battle of the web! Cool!&lt;/p&gt;

&lt;h3&gt;Programming Languages&lt;/h3&gt;

&lt;p&gt;In the area of programming languages, both client (not web) and server, dynamic is not winning, yet. Even though languages like C# and Objective-C are becoming more and more dynamic, they are still nowhere near Ruby and Python.
Java has stagnated and Scala is even more typeful than Java, although type inference relieves you from having to declare most of the types. Clojure is an interesting dynamic JVM language but it suffers since you still have to compile the code.&lt;/p&gt;

&lt;p&gt;But dynamic will win when it comes to programming languages too. Why? For the same reasons that dynamic is winning everywhere else. They are more suited for solving ever changing problems. The problems I try to solve everyday, always has to do with integrating with something else, and it is much easier to do with dynamic programming languages.&lt;/p&gt;

&lt;p&gt;So why is dynamic not winning in the area of client and server programming? I think there are a few reasons.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Education, most of us have been taught programming at a university that propagates for statically typed, compiled languages. We have been taught that dynamic languages are bad and that they may be suitable for scripting but nothing else. It has been hammered into us, so hard that we have a hard time letting go of this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tradition, the folklore says that dynamic programming languages are too slow. The fact that they are not, has not changed this. You may remember that the argument was the same against Java fifteen years ago.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And then there is the main reason, dynamic is harder!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Dynamic is Harder&lt;/h2&gt;

&lt;p&gt;So why isn't everyone using dynamic programming langugages? Because, it is harder. It is easier to write really bad code in dynamic languages. But, on the other hand, it is also easier to write really good code in dynamic languages.&lt;/p&gt;

&lt;p&gt;It is harder to develop large systems, because when you are using convention over configuration, it is really important to know the conventions and most people don't take the time to learn what they use properly, they rely on the IDE for guiding them down the right path.
If you are suffering from IDEitis, the transition to dynamic languages is going to be tough until you realize that the help you get from the IDE is also what is holding you back.&lt;/p&gt;

&lt;p&gt;The problem is moved from the programming language to me, the programmer, architect or whatever title I feel entitled to. If I am using a dynamic language and I screw up, it is my fault. If I don't organize the code in a way that can be understood by others, it is my fault. If I make changes to core classes, and the system stops working, it is my fault. I am responsible! I am in control!&lt;/p&gt;

&lt;h3&gt;An example, third party libraries in Ruby&lt;/h3&gt;

&lt;p&gt;I remember a comment from one of my colleagues, when he found out that I had a problem with a library (a Ruby Gem) that didn't behave the way I wanted it too.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Ah, you're using Ruby, then you can just fix it. -- Mattias Arthursson&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Right on Mattias, I can just fix it!&lt;/p&gt;

&lt;p&gt;Almost every Ruby Gem lives at Github. The flexibility this brings is tremendous. If a library is not working the way I think it should, I can just fix it. The process goes something like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fork it&lt;/li&gt;
&lt;li&gt;Make the appropriate changes&lt;/li&gt;

&lt;li&gt;Push it back up to Github (to my fork)&lt;/li&gt;
&lt;li&gt;Change the Gemfile, that holds my project dependencies, to use my fork instead.&lt;/li&gt;
&lt;li&gt;Optionally, I may also send a pull requests of my patch to the maintainer of the library.&lt;/li&gt;
&lt;li&gt;The maintainer takes a look at it and pulls it in, relieving me of the burden of keeping my fork up to date.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The process is so simple, it is almost seamless.&lt;/p&gt;

&lt;p&gt;I'll finish with another quote.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;It is vain to do with more, what can be done with less. -- William of Occam&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;It's a new year, it is time to prepare for the future, a dynamic future! Here are some books that I can recommend, they are about Ruby and Javascript, since they are my current favorites. But if you like other dynamic languages better, knock yourself out!&lt;/p&gt;

&lt;h2&gt;Books&lt;/h2&gt;

&lt;p&gt;The books are ordered, by increasing level of complexity.&lt;/p&gt;

&lt;h3&gt;Ruby&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Well-Grounded-Rubyist-David-Black/dp/1933988657/ref=sr_1_1?tag=thtasta-20"&gt;The Well Grounded Rubyist&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="http://www.amazon.com/Ruby-Way-Second-Techniques-Programming/dp/0672328844/ref=sr_1_1?tag=thtasta-20"&gt;The Ruby Way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Ruby-Best-Practices-Gregory-Brown/dp/0596523009/ref=sr_1_1?tag=thtasta-20"&gt;Ruby Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Metaprogramming-Ruby-Program-Like-Pros/dp/1934356476/ref=sr_1_1?tag=thtasta-20"&gt;Metaprogramming Ruby&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Rails&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Beginning-Rails-Experts-Voice-Development/dp/1430224339/ref=sr_1_1?tag=thtasta-20"&gt;Beginning Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Rails-Way-Addison-Wesley-Professional-Ruby/dp/0321601661/ref=sr_1_1?tag=thtasta-20"&gt;The Rails 3 Way&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="http://pragprog.com/titles/jvrails/crafting-rails-applications"&gt;Crafting Rails Applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Javascript&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?tag=thtasta-20"&gt;Javascript, the Good Parts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752/ref=sr_1_1?tag=thtasta-20"&gt;Javascript Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Performance-JavaScript-Faster-Application-Interfaces/dp/059680279X/ref=sr_1_1?tag=thtasta-20"&gt;High Performance Javascript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;jQuery&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/jQuery-Action-Second-Bear-Bibeault/dp/1935182323/ref=sr_1_1?tag=thtasta-20"&gt;jQuery in Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/jQuery-Cookbook-Solutions-Examples-Developers/dp/0596159773/ref=sr_1_1?tag=thtasta-20"&gt;jQuery Cookbook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-2019417748752156863?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/2019417748752156863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=2019417748752156863' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2019417748752156863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2019417748752156863'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2011/01/dynamic-for-win.html' title='Dynamic For The Win'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-7562576580896097587</id><published>2010-12-30T12:00:00.002+01:00</published><updated>2010-12-30T12:08:49.435+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='notes'/><category scheme='http://www.blogger.com/atom/ns#' term='summary'/><title type='text'>Review of Crafting Rails Applications, by José Valim</title><content type='html'>&lt;p&gt;Jos&amp;eacute; Valim is one of the newest members of the Rails core team. Apart from this he has also developed some good gems, &lt;a href="https://github.com/plataformatec/devise"&gt;Devise&lt;/a&gt;, &lt;a href="https://github.com/plataformatec/responders"&gt;Responders&lt;/a&gt;, and &lt;a href="https://github.com/plataformatec/simple_form"&gt;SimpleForm&lt;/a&gt;, that I use for almost every project.&lt;/p&gt;

&lt;p&gt;And now he has written a book, a &lt;strong&gt;really&lt;/strong&gt; good book, about advanced Rails programming techniques, called &lt;a href="http://pragprog.com/titles/jvrails/crafting-rails-applications"&gt;Crafting Rails Applications&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The book is only 180 pages long, and contains 7 chapters. I wish more books was this thin. The books is written in a clear concise way. Jos&amp;eacute;'s lightweight test-driven approach clearly introduces every problem it intends to solve, and then solves the problem by introducing a new concept in the Rails framework. Most of the solutions are only a few lines of code, showing the power of Rails and also showing the power of having intimate knowledge of the framework. By hooking into the framework at appropriate places, Jos&amp;eacute; is able to provide elegant solutions to a range of problems.&lt;/p&gt;

&lt;p&gt;I highly recommend the book to anyone interested in Rails.&lt;/p&gt;

&lt;p&gt;If this was an ordinary book, this review could have ended here, but since the book is full of things I really wanted to know but didn't take the time to learn I decided to internalize them by describing parts of the book in my own words.&lt;/p&gt;

&lt;h2&gt;Chapter 1, Creating our own renderer&lt;/h2&gt;

&lt;p&gt;In this chapter we learn how to add a new renderer Rails. We add a renderer that handles generating PDF files with &lt;a href="http://prawn.majesticseacreature.com/"&gt;Prawn&lt;/a&gt;, allowing us to write code that looks like this.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; HomeController &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; ApplicationController 
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; index
    respond_to &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;format&lt;font color="#990000"&gt;|&lt;/font&gt; 
      format&lt;font color="#990000"&gt;.&lt;/font&gt;html
      &lt;i&gt;&lt;font color="#9A1900"&gt;# This is the new capability, pdf rendering.&lt;/font&gt;&lt;/i&gt;
      format&lt;font color="#990000"&gt;.&lt;/font&gt;pdf &lt;font color="#FF0000"&gt;{&lt;/font&gt; render &lt;font color="#990000"&gt;:&lt;/font&gt;pdf &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"contents"&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;To allow the following we first have to register pdf as a mime type. We can do this with:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000080"&gt;require&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;"action_controller"&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# Register a new mime type&lt;/font&gt;&lt;/i&gt;
Mime&lt;font color="#990000"&gt;::&lt;/font&gt;Type&lt;font color="#990000"&gt;.&lt;/font&gt;register &lt;font color="#FF0000"&gt;"application/pdf"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;pdf

&lt;i&gt;&lt;font color="#9A1900"&gt;# Registering the type allows us to write&lt;/font&gt;&lt;/i&gt;
respond_to &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;format&lt;font color="#990000"&gt;|&lt;/font&gt;
  format&lt;font color="#990000"&gt;.&lt;/font&gt;pdf
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;With that out of the way all we have to do is to register a renderer, that will handle the actual rendering of the registered mime type. This is done with:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000080"&gt;require&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;"prawn"&lt;/font&gt; 

&lt;i&gt;&lt;font color="#9A1900"&gt;# Adds a new renderer to ActionController.Renderers&lt;/font&gt;&lt;/i&gt;
ActionController&lt;font color="#990000"&gt;::&lt;/font&gt;Renderers&lt;font color="#990000"&gt;.&lt;/font&gt;add &lt;font color="#990000"&gt;:&lt;/font&gt;pdf &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;filename&lt;font color="#990000"&gt;,&lt;/font&gt; options&lt;font color="#990000"&gt;|&lt;/font&gt;
  pdf &lt;font color="#990000"&gt;=&lt;/font&gt; Prawn&lt;font color="#990000"&gt;::&lt;/font&gt;Document&lt;font color="#990000"&gt;.&lt;/font&gt;new pdf&lt;font color="#990000"&gt;.&lt;/font&gt;text render_to_string&lt;font color="#990000"&gt;(&lt;/font&gt;options&lt;font color="#990000"&gt;)&lt;/font&gt; 
  send_data&lt;font color="#990000"&gt;(&lt;/font&gt;pdf&lt;font color="#990000"&gt;.&lt;/font&gt;render&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;filename &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"#{filename}.pdf"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
      &lt;font color="#990000"&gt;:&lt;/font&gt;type &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"application/pdf"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;disposition &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"attachment"&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This is all that is needed to add a rendering of a new type to Rails. Jos&amp;eacute; also goes into details about other points of interest where the rendering stack can be customized.&lt;/p&gt;

&lt;h2&gt;Chapter 2, Easy models with Active Model&lt;/h2&gt;

&lt;p&gt;Active Model is a Rails module that abstracts common behavior needed by different kinds om models such as Active Record, Active Resource and third party modules like Mongoid. Apart from giving developers of new models utility functionality. Active Model also provides tests for being Active Model compliant. To be compliant means to play well with the Rails view and controllers.&lt;/p&gt;

&lt;p&gt;Jos&amp;eacute; implements a model for creating sending mail. In doing so he introduces us to a bunch of Active Model modules that will do our work for us.&lt;/p&gt;

&lt;p&gt;Here are the modules in alphabetical order:&lt;/p&gt;

&lt;h3&gt;ActiveModel::AttributeMethods&lt;/h3&gt;

&lt;p&gt;When you include &lt;code&gt;ActiveModel::AttributeMethods&lt;/code&gt; in your model, you get access to helper methods that will help you define additional methods for dealing with the attributes of your model. An example&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Tapir
  &lt;b&gt;&lt;font color="#0000FF"&gt;include&lt;/font&gt;&lt;/b&gt; ActiveModel&lt;font color="#990000"&gt;::&lt;/font&gt;AttributeMethods
   
  &lt;i&gt;&lt;font color="#9A1900"&gt;# Define the attributes &lt;/font&gt;&lt;/i&gt;
  attr_accessor &lt;font color="#FF0000"&gt;'name'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'color'&lt;/font&gt;

  &lt;i&gt;&lt;font color="#9A1900"&gt;# We want to create clear methods for every attribute&lt;/font&gt;&lt;/i&gt;
  attribute_method_prefix &lt;font color="#FF0000"&gt;'clear_'&lt;/font&gt;

  &lt;i&gt;&lt;font color="#9A1900"&gt;# We also want to have query methods for every attribute&lt;/font&gt;&lt;/i&gt;
  attribute_method_suffix &lt;font color="#FF0000"&gt;'?'&lt;/font&gt;

  &lt;i&gt;&lt;font color="#9A1900"&gt;# Define the attribute methods that will call the protected methods below&lt;/font&gt;&lt;/i&gt;
  define_attribute_methods &lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;'name'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;'color'&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;

protected
  &lt;i&gt;&lt;font color="#9A1900"&gt;# The name of this method corresponds to the prefix above&lt;/font&gt;&lt;/i&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; clear_attribute&lt;font color="#990000"&gt;(&lt;/font&gt;attribute&lt;font color="#990000"&gt;)&lt;/font&gt;
    send&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"#{attribute}="&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;nil&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  &lt;i&gt;&lt;font color="#9A1900"&gt;# The name of this method corresponds to the suffix above&lt;/font&gt;&lt;/i&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; attribute?&lt;font color="#990000"&gt;(&lt;/font&gt;attribute&lt;font color="#990000"&gt;)&lt;/font&gt;
    send&lt;font color="#990000"&gt;(&lt;/font&gt;attribute&lt;font color="#990000"&gt;).&lt;/font&gt;present?
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;   t &lt;font color="#990000"&gt;=&lt;/font&gt; Tapir&lt;font color="#990000"&gt;.&lt;/font&gt;new
 &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;#&amp;lt;Tapir:0x00000102769b90&amp;gt; &lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; t&lt;font color="#990000"&gt;.&lt;/font&gt;name&lt;font color="#990000"&gt;?&lt;/font&gt;
 &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;false&lt;/font&gt;&lt;/b&gt; 
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; t&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#009900"&gt;name&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;'kalle'&lt;/font&gt;
 &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"kalle"&lt;/font&gt; 
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; t&lt;font color="#990000"&gt;.&lt;/font&gt;name&lt;font color="#990000"&gt;?&lt;/font&gt;
 &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;true&lt;/font&gt;&lt;/b&gt; 
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; t&lt;font color="#990000"&gt;.&lt;/font&gt;clear_name
 &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; nil 
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; t&lt;font color="#990000"&gt;.&lt;/font&gt;name&lt;font color="#990000"&gt;?&lt;/font&gt;
 &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;false&lt;/font&gt;&lt;/b&gt; 
&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; t&lt;font color="#990000"&gt;.&lt;/font&gt;name
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This is the gist of attribute methods, there is also an affix method that will allow you to add both a suffix and a prefix to your attributes. It is also worth taking a look inside the implmentation of this module, since the methods are defined on first usage through method_missing.&lt;/p&gt;

&lt;h3&gt;ActiveModel::Callbacks&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ActiveModel::Callbacks&lt;/code&gt; provides methods for creating &lt;code&gt;before_&lt;/code&gt;, &lt;code&gt;after_&lt;/code&gt;, and `around_' callbacks to your model methods. An example:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Tapir
  extend ActiveModel&lt;font color="#990000"&gt;::&lt;/font&gt;Callbacks

  define_model_callbacks &lt;font color="#990000"&gt;:&lt;/font&gt;snort

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; snort
    _run_snort_callbacks &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
      snort_snort_snort
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Then in inheriting classes I can use the callbacks as such:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; MountainTapir &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; Tapir
  before_snort &lt;font color="#990000"&gt;:&lt;/font&gt;do_before_snort

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; before_snort
    i_am_so_cold
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h3&gt;ActiveModel::Conversion&lt;/h3&gt;

&lt;p&gt;This module assists with converting to, and representing a specific model instance. It contains three methods.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;to_model&lt;/code&gt;, used for converting to an active model compliant model, in the default case it just returns &lt;code&gt;self&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;to_param&lt;/code&gt;, used for representing a model in routing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;to_key&lt;/code&gt;, used for representing a model from in a dom page.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;ActiveModel::Naming and ActiveModel::Translation&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ActiveModel::Naming&lt;/code&gt; contains one method &lt;code&gt;model_name&lt;/code&gt;, that returns a subclass of String, that handles pluralization, etc. It has methods such as &lt;code&gt;plural&lt;/code&gt;, &lt;code&gt;human&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ActiveModel::Translation&lt;/code&gt; deals with I18N by adding functionality to &lt;code&gt;human&lt;/code&gt; that handles the name lookup by keys using the preferred &lt;code&gt;I18n.backend&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;ActiveModel::Validations&lt;/h3&gt;

&lt;p&gt;The last, but not least of the models, &lt;code&gt;ActiveModel::Validations&lt;/code&gt;, deals with validations. Jos&amp;eacute; demostrates how naming convetions and Rails constant lookup allow us to add new validators to Rails with ease. An example:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;module&lt;/font&gt;&lt;/b&gt; Validators
  &lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; TapirKindValidator &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; ActiveModel&lt;font color="#990000"&gt;::&lt;/font&gt;EachValidator 
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; validate_each&lt;font color="#990000"&gt;(&lt;/font&gt;record&lt;font color="#990000"&gt;,&lt;/font&gt; attribute&lt;font color="#990000"&gt;,&lt;/font&gt; value&lt;font color="#990000"&gt;)&lt;/font&gt;
      &lt;b&gt;&lt;font color="#0000FF"&gt;unless&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;[:&lt;/font&gt;baird&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;mountain&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;malayan&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;lowland&lt;font color="#990000"&gt;].&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;include&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;?&lt;/font&gt; value
        record&lt;font color="#990000"&gt;.&lt;/font&gt;errors&lt;font color="#990000"&gt;.&lt;/font&gt;add&lt;font color="#990000"&gt;(&lt;/font&gt;attribute&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;invalid&lt;font color="#990000"&gt;,&lt;/font&gt; options&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;


&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;If I now include my new validator wherever I want to use it. I can write code like:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Tapir
  &lt;b&gt;&lt;font color="#0000FF"&gt;include&lt;/font&gt;&lt;/b&gt; Validators
  
  attr_accessor &lt;font color="#990000"&gt;:&lt;/font&gt;kind
  validates &lt;font color="#990000"&gt;:&lt;/font&gt;kind&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;tapir_kind &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;true&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

t &lt;font color="#990000"&gt;=&lt;/font&gt; Tapir&lt;font color="#990000"&gt;.&lt;/font&gt;new &lt;font color="#990000"&gt;:&lt;/font&gt;kind &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;mexican
t&lt;font color="#990000"&gt;.&lt;/font&gt;valid? 
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; false&lt;/font&gt;&lt;/i&gt;
t&lt;font color="#990000"&gt;.&lt;/font&gt;errors&lt;font color="#990000"&gt;[:&lt;/font&gt;kind&lt;font color="#990000"&gt;]&lt;/font&gt; 
&lt;i&gt;&lt;font color="#9A1900"&gt;# ["is invalid"]&lt;/font&gt;&lt;/i&gt;


&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This example is unnecessarily complicated, since the validation could be fixed with:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Tapir
    attr_accessor &lt;font color="#990000"&gt;:&lt;/font&gt;kind
    validates_inclusion_of &lt;font color="#990000"&gt;:&lt;/font&gt;kind&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt;  &lt;font color="#990000"&gt;[:&lt;/font&gt;baird&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;mountain&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;malayan&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;lowland&lt;font color="#990000"&gt;]&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h3&gt;append_view_path&lt;/h3&gt;

&lt;p&gt;There is one more interesting thing in this chapter, &lt;code&gt;append_view_path&lt;/code&gt;. It can be used to add a directory inside a gem to the view lookup path. This is essential to be able to deliver custom Rails components, Railties, with default views.&lt;/p&gt;

&lt;h2&gt;Chapter 3, Building a template management system&lt;/h2&gt;

&lt;p&gt;In the third chapter of the book,Jos&amp;eacute; takes on view resolvers. A resolver is responsible for looking up the appropriate template for a given request. The traditional resolver looks up the templates by path in the file system, but Jos&amp;eacute; guides us through creating a resolver that looks up the template in a database. Perfect for the core of a CMS system. I'm going to alter Jos&amp;eacute;'s resolver to do the lookup in MongoDB instead.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Most of this code is borrowed directly from Jos&amp;amp;eacute; Valim&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# Only the Mongoid Part is written by me :)&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#000080"&gt;require&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;'mongoid'&lt;/font&gt;
&lt;b&gt;&lt;font color="#000080"&gt;require&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;'singleton'&lt;/font&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; MongoTemplate
  &lt;b&gt;&lt;font color="#0000FF"&gt;include&lt;/font&gt;&lt;/b&gt; Mongoid&lt;font color="#990000"&gt;::&lt;/font&gt;Document
  field &lt;font color="#990000"&gt;:&lt;/font&gt;body
  field &lt;font color="#990000"&gt;:&lt;/font&gt;path
  field &lt;font color="#990000"&gt;:&lt;/font&gt;locale
  field &lt;font color="#990000"&gt;:&lt;/font&gt;format
  field &lt;font color="#990000"&gt;:&lt;/font&gt;handler
  field &lt;font color="#990000"&gt;:&lt;/font&gt;partial&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;type &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; Boolean
  field &lt;font color="#990000"&gt;:&lt;/font&gt;updated_at&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;type &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; Date
    
  validates &lt;font color="#990000"&gt;:&lt;/font&gt;body&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;path&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;presence &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;true&lt;/font&gt;&lt;/b&gt;
  validates &lt;font color="#990000"&gt;:&lt;/font&gt;format&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;inclusion &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; Mime&lt;font color="#990000"&gt;::&lt;/font&gt;SET&lt;font color="#990000"&gt;.&lt;/font&gt;symbols&lt;font color="#990000"&gt;.&lt;/font&gt;map&lt;font color="#990000"&gt;(&amp;amp;:&lt;/font&gt;to_s&lt;font color="#990000"&gt;)&lt;/font&gt; 
  validates &lt;font color="#990000"&gt;:&lt;/font&gt;locale&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;inclusion &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; I18n&lt;font color="#990000"&gt;.&lt;/font&gt;available_locales&lt;font color="#990000"&gt;.&lt;/font&gt;map&lt;font color="#990000"&gt;(&amp;amp;:&lt;/font&gt;to_s&lt;font color="#990000"&gt;)&lt;/font&gt; 
  validates &lt;font color="#990000"&gt;:&lt;/font&gt;handler&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;inclusion &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; 
    ActionView&lt;font color="#990000"&gt;::&lt;/font&gt;Template&lt;font color="#990000"&gt;::&lt;/font&gt;Handlers&lt;font color="#990000"&gt;.&lt;/font&gt;extensions&lt;font color="#990000"&gt;.&lt;/font&gt;map&lt;font color="#990000"&gt;(&amp;amp;:&lt;/font&gt;to_s&lt;font color="#990000"&gt;)&lt;/font&gt;

  &lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Resolver &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; ActionView&lt;font color="#990000"&gt;::&lt;/font&gt;Resolver 
    &lt;b&gt;&lt;font color="#0000FF"&gt;include&lt;/font&gt;&lt;/b&gt; Singleton
  protected
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; find_templates&lt;font color="#990000"&gt;(&lt;/font&gt;name&lt;font color="#990000"&gt;,&lt;/font&gt; prefix&lt;font color="#990000"&gt;,&lt;/font&gt; partial&lt;font color="#990000"&gt;,&lt;/font&gt; details&lt;font color="#990000"&gt;)&lt;/font&gt;
      conditions &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
        &lt;font color="#990000"&gt;:&lt;/font&gt;path &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; normalize_path&lt;font color="#990000"&gt;(&lt;/font&gt;name&lt;font color="#990000"&gt;,&lt;/font&gt; prefix&lt;font color="#990000"&gt;),&lt;/font&gt;
        &lt;font color="#990000"&gt;:&lt;/font&gt;locale &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; normalize_array&lt;font color="#990000"&gt;(&lt;/font&gt;details&lt;font color="#990000"&gt;[:&lt;/font&gt;locale&lt;font color="#990000"&gt;]).&lt;/font&gt;first&lt;font color="#990000"&gt;,&lt;/font&gt; 
        &lt;font color="#990000"&gt;:&lt;/font&gt;format &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; normalize_array&lt;font color="#990000"&gt;(&lt;/font&gt;details&lt;font color="#990000"&gt;[:&lt;/font&gt;formats&lt;font color="#990000"&gt;]).&lt;/font&gt;first&lt;font color="#990000"&gt;,&lt;/font&gt;
        &lt;font color="#990000"&gt;:&lt;/font&gt;handler&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; normalize_array&lt;font color="#990000"&gt;(&lt;/font&gt;details&lt;font color="#990000"&gt;[:&lt;/font&gt;handlers&lt;font color="#990000"&gt;]),&lt;/font&gt; 
        &lt;font color="#990000"&gt;:&lt;/font&gt;partial &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; partial &lt;font color="#990000"&gt;||&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;false&lt;/font&gt;&lt;/b&gt;
      &lt;font color="#FF0000"&gt;}&lt;/font&gt;
   
      MongoTemplate&lt;font color="#990000"&gt;.&lt;/font&gt;where&lt;font color="#990000"&gt;(&lt;/font&gt;conditions&lt;font color="#990000"&gt;).&lt;/font&gt;map &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;record&lt;font color="#990000"&gt;|&lt;/font&gt; 
        initialize_template&lt;font color="#990000"&gt;(&lt;/font&gt;record&lt;font color="#990000"&gt;)&lt;/font&gt;
      &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
    
    &lt;i&gt;&lt;font color="#9A1900"&gt;# Normalize name and prefix, so the tuple ["index", "users"] becomes &lt;/font&gt;&lt;/i&gt;
    &lt;i&gt;&lt;font color="#9A1900"&gt;# "users/index" and the tuple ["template", nil] becomes "template". &lt;/font&gt;&lt;/i&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; normalize_path&lt;font color="#990000"&gt;(&lt;/font&gt;name&lt;font color="#990000"&gt;,&lt;/font&gt; prefix&lt;font color="#990000"&gt;)&lt;/font&gt;
      prefix&lt;font color="#990000"&gt;.&lt;/font&gt;present? &lt;font color="#990000"&gt;?&lt;/font&gt; &lt;font color="#FF0000"&gt;"#{prefix}/#{name}"&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; name
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
   
    &lt;i&gt;&lt;font color="#9A1900"&gt;# Normalize arrays by converting all symbols to strings.&lt;/font&gt;&lt;/i&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; normalize_array&lt;font color="#990000"&gt;(&lt;/font&gt;array&lt;font color="#990000"&gt;)&lt;/font&gt;
      array&lt;font color="#990000"&gt;.&lt;/font&gt;map&lt;font color="#990000"&gt;(&amp;amp;:&lt;/font&gt;to_s&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

    &lt;i&gt;&lt;font color="#9A1900"&gt;# Initialize an ActionView::Template object based on the record found.&lt;/font&gt;&lt;/i&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; initialize_template&lt;font color="#990000"&gt;(&lt;/font&gt;record&lt;font color="#990000"&gt;)&lt;/font&gt; 
      source &lt;font color="#990000"&gt;=&lt;/font&gt; record&lt;font color="#990000"&gt;.&lt;/font&gt;body 
      identifier &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;"MongoTemplate - #{record.id} - #{record.path.inspect}"&lt;/font&gt; 
      handler &lt;font color="#990000"&gt;=&lt;/font&gt; ActionView&lt;font color="#990000"&gt;::&lt;/font&gt;Template&lt;font color="#990000"&gt;.&lt;/font&gt;registered_template_handler&lt;font color="#990000"&gt;(&lt;/font&gt;record&lt;font color="#990000"&gt;.&lt;/font&gt;handler&lt;font color="#990000"&gt;)&lt;/font&gt;
      details &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; 
        &lt;font color="#990000"&gt;:&lt;/font&gt;format &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; Mime&lt;font color="#990000"&gt;[&lt;/font&gt;record&lt;font color="#990000"&gt;.&lt;/font&gt;format&lt;font color="#990000"&gt;],&lt;/font&gt; 
        &lt;font color="#990000"&gt;:&lt;/font&gt;updated_at &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; record&lt;font color="#990000"&gt;.&lt;/font&gt;updated_at&lt;font color="#990000"&gt;,&lt;/font&gt; 
        &lt;font color="#990000"&gt;:&lt;/font&gt;virtual_path &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; virtual_path&lt;font color="#990000"&gt;(&lt;/font&gt;record&lt;font color="#990000"&gt;.&lt;/font&gt;path&lt;font color="#990000"&gt;,&lt;/font&gt; record&lt;font color="#990000"&gt;.&lt;/font&gt;partial&lt;font color="#990000"&gt;)&lt;/font&gt;
      &lt;font color="#FF0000"&gt;}&lt;/font&gt;
      ActionView&lt;font color="#990000"&gt;::&lt;/font&gt;Template&lt;font color="#990000"&gt;.&lt;/font&gt;new&lt;font color="#990000"&gt;(&lt;/font&gt;source&lt;font color="#990000"&gt;,&lt;/font&gt; identifier&lt;font color="#990000"&gt;,&lt;/font&gt; handler&lt;font color="#990000"&gt;,&lt;/font&gt; details&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
    
    &lt;i&gt;&lt;font color="#9A1900"&gt;# Make paths as "users/user" become "users/_user" for partials.&lt;/font&gt;&lt;/i&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; virtual_path&lt;font color="#990000"&gt;(&lt;/font&gt;path&lt;font color="#990000"&gt;,&lt;/font&gt; partial&lt;font color="#990000"&gt;)&lt;/font&gt; 
      &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; path &lt;b&gt;&lt;font color="#0000FF"&gt;unless&lt;/font&gt;&lt;/b&gt; partial 
      &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; index &lt;font color="#990000"&gt;=&lt;/font&gt; path&lt;font color="#990000"&gt;.&lt;/font&gt;rindex&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"/"&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
        path&lt;font color="#990000"&gt;.&lt;/font&gt;insert&lt;font color="#990000"&gt;(&lt;/font&gt;index &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"_"&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
      &lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt;
        &lt;font color="#FF0000"&gt;"_#{path}"&lt;/font&gt;
      &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;A Resolver is implemented by extending &lt;code&gt;ActionView::Resolver&lt;/code&gt; and implementing the method &lt;code&gt;find_templates(name, prefix, partial, details)&lt;/code&gt; There are a lot of extra information in the book, about caching etc. Obviously Rails caches the templates since it would be too slow to create a template every time. That is why we have the template as a singleton and that is why we clear the cache in the &lt;code&gt;after_save&lt;/code&gt; hook above. The hook in Mongoid works exactly the same as in Active Record. Thank you Active Model!&lt;/p&gt;

&lt;h2&gt;Chapter 4, Multipart Emails with Markdown and Erb&lt;/h2&gt;

&lt;p&gt;In this chapter Jos&amp;eacute; walks us through three topics. The template handler API, Rails generators and Railties. I'm going to skip over the last two in this chapter. Generators are a large topic and they deserve a blog post of their own. Jos&amp;eacute; does a great job desribing how they work. The same goes for Railties and Rails Engines, they are definitely worthy of a blog post of their own.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# &lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# Again most of the code is stolen from Jos&amp;amp;eacute; :)&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;#&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;module&lt;/font&gt;&lt;/b&gt; ScrambleHandler
  
  &lt;i&gt;&lt;font color="#9A1900"&gt;# Lookup the ERb handler&lt;/font&gt;&lt;/i&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;erb_handler
    &lt;font color="#009900"&gt;@@erb_handler&lt;/font&gt; &lt;font color="#990000"&gt;||=&lt;/font&gt; ActionView&lt;font color="#990000"&gt;::&lt;/font&gt;Template&lt;font color="#990000"&gt;.&lt;/font&gt;registered_template_handler&lt;font color="#990000"&gt;(:&lt;/font&gt;erb&lt;font color="#990000"&gt;)&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;call&lt;font color="#990000"&gt;(&lt;/font&gt;template&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;i&gt;&lt;font color="#9A1900"&gt;# Call the erb handler, then call the new scrambler method.&lt;/font&gt;&lt;/i&gt;
    source &lt;font color="#990000"&gt;=&lt;/font&gt; erb_handler&lt;font color="#990000"&gt;.&lt;/font&gt;call&lt;font color="#990000"&gt;(&lt;/font&gt;template&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; template&lt;font color="#990000"&gt;.&lt;/font&gt;formats&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;include&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;?(:&lt;/font&gt;html&lt;font color="#990000"&gt;)&lt;/font&gt;
      &lt;font color="#FF0000"&gt;"Scrambler.from_html(begin;#{source};end).to_s"&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt;
      &lt;font color="#FF0000"&gt;"Scrambler.from_text(begin;#{source};end).to_s"&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Register our new handler, it handles index.html.scramble, show.html.scramble, ...&lt;/font&gt;&lt;/i&gt;
ActionView&lt;font color="#990000"&gt;::&lt;/font&gt;Template&lt;font color="#990000"&gt;.&lt;/font&gt;register_template_handler &lt;font color="#990000"&gt;:&lt;/font&gt;scramble&lt;font color="#990000"&gt;,&lt;/font&gt; ScrambleHandler

&lt;i&gt;&lt;font color="#9A1900"&gt;# This module scrambles text.&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# Scrambler.from_text('Once upon a time a beautiful tapir came.')&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# -&amp;gt; Ocne upon a time a baeuuitfl tpiar came.&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;module&lt;/font&gt;&lt;/b&gt; Scrambler
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;from_html html
    doc &lt;font color="#990000"&gt;=&lt;/font&gt; Nokogiri&lt;font color="#990000"&gt;::&lt;/font&gt;HTML&lt;font color="#990000"&gt;(&lt;/font&gt;html&lt;font color="#990000"&gt;)&lt;/font&gt; 
    doc&lt;font color="#990000"&gt;.&lt;/font&gt;xpath&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'//text()'&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;each &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;node&lt;font color="#990000"&gt;|&lt;/font&gt;
      node&lt;font color="#990000"&gt;.&lt;/font&gt;content &lt;font color="#990000"&gt;=&lt;/font&gt; from_text&lt;font color="#990000"&gt;(&lt;/font&gt;node&lt;font color="#990000"&gt;.&lt;/font&gt;content&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
    doc&lt;font color="#990000"&gt;.&lt;/font&gt;to_html
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;from_text text
    tokenize&lt;font color="#990000"&gt;(&lt;/font&gt;text&lt;font color="#990000"&gt;).&lt;/font&gt;map&lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#990000"&gt;|&lt;/font&gt;token&lt;font color="#990000"&gt;|&lt;/font&gt; scramble&lt;font color="#990000"&gt;(&lt;/font&gt;token&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;join&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;''&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;tokenize text
    &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;nil&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;unless&lt;/font&gt;&lt;/b&gt; text
    text&lt;font color="#990000"&gt;.&lt;/font&gt;scan&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF6600"&gt;/(\p{Word}+|\W+|)/&lt;/font&gt;um&lt;font color="#990000"&gt;).&lt;/font&gt;flatten
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;scramble word
    &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; word &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; word &lt;font color="#990000"&gt;=~&lt;/font&gt; &lt;font color="#FF6600"&gt;/\W/&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; word &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; word&lt;font color="#990000"&gt;.&lt;/font&gt;size &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; &lt;font color="#993399"&gt;4&lt;/font&gt;
    arr &lt;font color="#990000"&gt;=&lt;/font&gt; word&lt;font color="#990000"&gt;.&lt;/font&gt;split&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF6600"&gt;//&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
    arr&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; arr&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;...-&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;].&lt;/font&gt;shuffle&lt;font color="#990000"&gt;.&lt;/font&gt;join&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;''&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; arr&lt;font color="#990000"&gt;[-&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Chapter 5, Publishing and subscribing to your applications events&lt;/h2&gt;

&lt;p&gt;In this chapter Jos&amp;eacute; uses the Notifications API to store notifcations in a MongoDB. He also shows how to use Rack middleware to configure what request to log. In order to configure the middleware he uses a Rails Engine. I'm just going to show how the Notifications API works here, and I'll let you read the rest in the book.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Subscribe to all events and print them to the console&lt;/font&gt;&lt;/i&gt;
ActiveSupport&lt;font color="#990000"&gt;::&lt;/font&gt;Notifications&lt;font color="#990000"&gt;.&lt;/font&gt;subscribe &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|*&lt;/font&gt;args&lt;font color="#990000"&gt;|&lt;/font&gt;
  p ActiveSupport&lt;font color="#990000"&gt;::&lt;/font&gt;Notifications&lt;font color="#990000"&gt;::&lt;/font&gt;Event&lt;font color="#990000"&gt;.&lt;/font&gt;new&lt;font color="#990000"&gt;(*&lt;/font&gt;args&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Instrument the rendering of Foo&lt;/font&gt;&lt;/i&gt;
ActiveSupport&lt;font color="#990000"&gt;::&lt;/font&gt;Notifications&lt;font color="#990000"&gt;.&lt;/font&gt;instrument&lt;font color="#990000"&gt;(:&lt;/font&gt;render&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;extra &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;information&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
  render &lt;font color="#990000"&gt;:&lt;/font&gt;text &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"Foo"&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;


&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Chapter 6, DRY controllers with Responders&lt;/h2&gt;

&lt;p&gt;In this chapter Jos&amp;eacute; goes through the implementation of responders. This implementation allows you to DRY up your controllers by factoring out common behavior.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; index
  &lt;font color="#009900"&gt;@users&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; User&lt;font color="#990000"&gt;.&lt;/font&gt;all
  respond_to &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;format&lt;font color="#990000"&gt;|&lt;/font&gt; 
    format&lt;font color="#990000"&gt;.&lt;/font&gt;html &lt;i&gt;&lt;font color="#9A1900"&gt;# index.html.erb &lt;/font&gt;&lt;/i&gt;
    format&lt;font color="#990000"&gt;.&lt;/font&gt;xml &lt;font color="#FF0000"&gt;{&lt;/font&gt; render &lt;font color="#990000"&gt;:&lt;/font&gt;xml &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#009900"&gt;@users&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# becomes&lt;/font&gt;&lt;/i&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; index 
  &lt;font color="#009900"&gt;@users&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; User&lt;font color="#990000"&gt;.&lt;/font&gt;all 
  respond_with&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;@users&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;


&lt;i&gt;&lt;font color="#9A1900"&gt;# and&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; create 
  &lt;font color="#009900"&gt;@user&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; User&lt;font color="#990000"&gt;.&lt;/font&gt;new&lt;font color="#990000"&gt;(&lt;/font&gt;params&lt;font color="#990000"&gt;[:&lt;/font&gt;user&lt;font color="#990000"&gt;])&lt;/font&gt;
  respond_to &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;format&lt;font color="#990000"&gt;|&lt;/font&gt; 
  &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;@user&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;save
    format&lt;font color="#990000"&gt;.&lt;/font&gt;html &lt;font color="#FF0000"&gt;{&lt;/font&gt; redirect_to&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;@user&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;notice &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;'User was successfully created.'&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;
    format&lt;font color="#990000"&gt;.&lt;/font&gt;xml &lt;font color="#FF0000"&gt;{&lt;/font&gt; render &lt;font color="#990000"&gt;:&lt;/font&gt;xml &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#009900"&gt;@user&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;status &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;created&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;location &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#009900"&gt;@user&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt;
    format&lt;font color="#990000"&gt;.&lt;/font&gt;html &lt;font color="#FF0000"&gt;{&lt;/font&gt; render &lt;font color="#990000"&gt;:&lt;/font&gt;action &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"new"&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt; 
    format&lt;font color="#990000"&gt;.&lt;/font&gt;xml &lt;font color="#FF0000"&gt;{&lt;/font&gt; render &lt;font color="#990000"&gt;:&lt;/font&gt;xml &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#009900"&gt;@user&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;errors&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;status &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;unprocessable_entity &lt;font color="#FF0000"&gt;}&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt; 
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# becomes&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; create 
  &lt;font color="#009900"&gt;@user&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; User&lt;font color="#990000"&gt;.&lt;/font&gt;new&lt;font color="#990000"&gt;(&lt;/font&gt;params&lt;font color="#990000"&gt;[:&lt;/font&gt;user&lt;font color="#990000"&gt;])&lt;/font&gt; 
  flash&lt;font color="#990000"&gt;[:&lt;/font&gt;notice&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;'User was successfully created.'&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;@user&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;save 
  respond_with&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;@user&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;In this chapter we also learn how to replace the default generators with our own customized generators.&lt;/p&gt;

&lt;h2&gt;Chapter 7, Translatable app with I18n and Redis&lt;/h2&gt;

&lt;p&gt;In the final chapter Jos&amp;eacute; shows us how the I18N backed system works. He does this by creating a backend the uses Redis instead of the default YAML files. He also developes a simple Sinatra application that he hooks into the Rails routing with the &lt;code&gt;mount&lt;/code&gt; method.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Mount the Sinatra Translator::App at the /translator path.&lt;/font&gt;&lt;/i&gt;
mount Translator&lt;font color="#990000"&gt;::&lt;/font&gt;App&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;at &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"/translator"&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Rack applications normally get the full path inside &lt;code&gt;ENV['PATH_INFO']&lt;/code&gt;, but when Rails mounts an application it removes the prefix before it sends it on &lt;code&gt;/translator/en/pt/&lt;/code&gt; becomes &lt;code&gt;/en/pt/&lt;/code&gt;. The additional path is sent on in &lt;code&gt;ENV['SCRIPT_NAME'] = '/translator'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We also get a brief overview of Devise, the state-of-the-art authentication solution written by Jos&amp;eacute; himself.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;One last thing, the book I have reviewed is a beta book, but the quality of it is higher than most published books I have seen. Congratulations to Jos&amp;eacute; and to the pragmatic bookshelf! There is not much more to say, get the book.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-7562576580896097587?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/7562576580896097587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=7562576580896097587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7562576580896097587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7562576580896097587'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/12/review-of-crafting-rails-applications.html' title='Review of Crafting Rails Applications, by Jos&amp;eacute; Valim'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-5726312123206250126</id><published>2010-10-27T10:35:00.000+02:00</published><updated>2010-10-27T10:35:14.252+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Java and Javascript in a Nutshell</title><content type='html'>&lt;div style="float:left"&gt;
&lt;h2&gt;Java&lt;/h2&gt;
&lt;img border="0" height="400" src="http://3.bp.blogspot.com/_ELioussa2vo/TMfhNaYINEI/AAAAAAAAAgI/0Ho2olrrDws/s400/coconut.jpg" style="border-width: 0;" width="297" /&gt;
&lt;/div&gt;

&lt;div style="float:left; margin-left: 4em; "&gt;
&lt;h2&gt;Javascript&lt;/h2&gt;
&lt;img border="0" src="http://3.bp.blogspot.com/_ELioussa2vo/TMfhUUphBlI/AAAAAAAAAgM/bBBN5pl_M_Y/s1600/peanut.jpg" style="border-width: 0;" /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-5726312123206250126?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/5726312123206250126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=5726312123206250126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/5726312123206250126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/5726312123206250126'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/10/java-and-javascript-in-nutshell.html' title='Java and Javascript in a Nutshell'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ELioussa2vo/TMfhNaYINEI/AAAAAAAAAgI/0Ho2olrrDws/s72-c/coconut.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-5090927032619689755</id><published>2010-10-04T07:31:00.000+02:00</published><updated>2010-10-04T07:31:35.968+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='mind'/><title type='text'>Choices, Habits and Awareness</title><content type='html'>&lt;p&gt;Every second, the human brain is bombarded with information, the conscious part of the brain is only able to handle a tiny percentage of this. The rest is handled by our unconscious.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;habit&lt;/em&gt; is an automatic reaction to a given situation. Habits allow us to do things automatically, without being consciously &lt;em&gt;aware&lt;/em&gt; of what we are doing. But, to form a new habit takes time, and during that time we must &lt;em&gt;choose&lt;/em&gt; to do what we want to make a habit of. And, to be able to make this choice we must be aware of the choice in the first place. &lt;em&gt;We must be aware to be able to become unaware!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is an algorithm to illustrate this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Sequential&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;not&lt;/font&gt;&lt;/b&gt; habit?&lt;font color="#990000"&gt;(&lt;/font&gt;choice&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;or&lt;/font&gt;&lt;/b&gt; aware_of?&lt;font color="#990000"&gt;(&lt;/font&gt;choice&lt;font color="#990000"&gt;)&lt;/font&gt;
  make_decision&lt;font color="#990000"&gt;(&lt;/font&gt;choice&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt;
  automatic_response&lt;font color="#990000"&gt;(&lt;/font&gt;choice&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Of course, it is not that simple. The brain is not sequential.&lt;/p&gt;

&lt;p&gt;The brain is massively parallel and almost everything in it happens unconsciously. Every second our senses are fed with more than 11 million bits of information, while the conscious part of our brain is only able to process less than 50! All other information is filtered out by our unconscious. Scary! But, here comes the cool part, &lt;em&gt;we can consciously change our filters by creating new habits&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Here is parallel version of the code above.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Parallel, unconscious&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; habit?&lt;font color="#990000"&gt;(&lt;/font&gt;choice&lt;font color="#990000"&gt;)&lt;/font&gt;
  automatic_response&lt;font color="#990000"&gt;(&lt;/font&gt;choice&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Parallel, conscious&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; aware_of&lt;font color="#990000"&gt;(&lt;/font&gt;choice&lt;font color="#990000"&gt;)&lt;/font&gt;
  make_decision&lt;font color="#990000"&gt;(&lt;/font&gt;choice&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# Practice&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Choices&lt;/h2&gt;

&lt;p&gt;Every single moment of our life, we are given choices. Some choices are obvious (the choices are, the answers may not be) such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should I use Ruby or Python for my next project?&lt;/li&gt;
&lt;li&gt;Do you take this woman to be your lawfully wedded wife?&lt;/li&gt;
&lt;li&gt;Should I learn a new programming language that I have no hope, whatsoever, to use in a live project?&lt;/li&gt;
&lt;li&gt;Are the kids allowed to play with fire?&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Other choices are not so clear, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I get up now or press snooze another time?&lt;/li&gt;
&lt;li&gt;Should I step on the white lines when crossing the street?&lt;/li&gt;
&lt;li&gt;Do I put the right foot in front of the left or jump on the left?&lt;/li&gt;
&lt;li&gt;Should I remove the hand from the hot stove or not?&lt;/li&gt;
&lt;li&gt;Should I react by being angry or not?&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;What's cool, and scary, with choices is that every time we make one, our brain changes. It literally changes physically every time. It actually changes every time we think a thought.&lt;/p&gt;

&lt;p&gt;Every time we make a certain choice, that path through the brain gets wider, and thus the choice gets easier to make. It is easier to make the same decision, over and over, than it is to make new decisions all the time.&lt;/p&gt;

&lt;p&gt;Another thing about choices is that it is often painful to make them. The reason for this, I believe, is that we often know, intuitively, what the right choice is, but that choice involves more work. This is why we should form good habits, because habits free us from the agony to choose.&lt;/p&gt;

&lt;h2&gt;Habits&lt;/h2&gt;

&lt;p&gt;When we have made a decision many times; when a path through the brain has become wide enough, we don't have to make a choice any more! We have formed a habit. Psychologists say that it takes 21 days. We have both good habits and bad ones. And most of the habits we have, we are unaware of.&lt;/p&gt;

&lt;p&gt;A great thing about &lt;em&gt;good&lt;/em&gt; habits is that they are performed by the unconscious part of the brain. They allow us to do things without consciously thinking about them. And since we are not consciously thinking about them, it is almost as if they do themselves. :D&lt;/p&gt;

&lt;p&gt;A sad thing about &lt;em&gt;bad&lt;/em&gt; habits is that they are performed by the unconscious part of the brain. We do things without consciously thinking about them. And since we are not consciously thinking about them, it is almost as if they do themselves. :(&lt;/p&gt;

&lt;p&gt;That is why we should nurture our habits. We should create habits of things that we want to do, like writing our tests first, and complimenting people when they do good. We should make habits of boring things, that we have to do, like doing the dishes and writing documentation. Once they become habits they are not boring anymore.&lt;/p&gt;

&lt;p&gt;This is also why we should be grateful when someone points out our bad habits, because they help us become aware of something that we may want to change.&lt;/p&gt;

&lt;h2&gt;Awareness&lt;/h2&gt;

&lt;p&gt;The key to forming new good habits and getting rid of bad ones, is &lt;em&gt;awareness&lt;/em&gt;. We cannot change what we are not aware of. We cannot train what we are not aware of. But what are we aware of? We are aware of things we are trained to be aware of. Our awareness is learned, it is dependent on our habits! Ah, recursion!&lt;/p&gt;

&lt;p&gt;When we are creating habits, we define ourselves.&lt;/p&gt;

&lt;p&gt;Are you aware that there is a &lt;a href="http://www.ruby-lang.org"&gt;programming language&lt;/a&gt; designed for programmer happiness?&lt;/p&gt;

&lt;p&gt;Are you aware that touch typing is a habit? That sitting in front of a computer eight hours a day without being able to touch type sucks? If you're not, read &lt;a href="http://steve-yegge.blogspot.com/2008/09/programmings-dirtiest-little-secret.html"&gt;this blog post&lt;/a&gt; by blogger extraordinaire, Steve Yegge. I wasn't aware two years ago but now I type 50 WPM (which is not great, but I get better every day).&lt;/p&gt;

&lt;p&gt;Are you aware of that your habits form your thoughts, that they form you?&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;We are what we repeatably do. --Aristotele&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Can you imagine a day without googling for code-related things? When you don't have to think at all about the signatures of methods, the key combinations that moves you to the right position, or the inner workings of the authentication library. Can you imagine how good you would feel, and how fast you would work? Can you imagine eight hours of continuous flow?&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Linus Torvalds, allegedly, wrote the bare bones of Git in two weeks. How could he do this? Because he has been living and breathing C and Linux, for the last 20 years!&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;So, where am I going with this?  I want flow! I want eight hours of continuous flow while I'm working. In order to achieve this, I have to train my brain to know, really know, unconsciously know, the tools of my trade.&lt;/p&gt;

&lt;p&gt;I am going to select a small number of tools that resonates with the way I am and want to work.&lt;/p&gt;

&lt;p&gt;I have previously been a generalist when it comes to programming. I am proficient in many programming languages, but I have yet to become a true expert in one. With a true expert I mean someone who doesn't have to lookup &lt;em&gt;anything&lt;/em&gt;. Everything, the language constructs, the built-in libraries, the major third-party libraries, the tools, should be intuitively known, habitual.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I aim to become an expert in the languages Javascript and Ruby.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This doesn't mean that I'll give up other programming languages. I will still dabble with interesting programming languages like Clojure, Scala, Mirah, etc., but my main focus will be on Ruby and Javascript.&lt;/p&gt;

&lt;p&gt;Why Ruby and Javascript? Because they are languages that resonates with my brain. They are dynamic, interpreted and give lightning-fast feedback. They also allow me to express my concepts clearly and succinctly.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-5090927032619689755?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/5090927032619689755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=5090927032619689755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/5090927032619689755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/5090927032619689755'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/10/choices-habits-and-awareness.html' title='Choices, Habits and Awareness'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-7010963155504705942</id><published>2010-09-29T18:47:00.000+02:00</published><updated>2010-09-29T18:47:23.630+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Why Ruby?</title><content type='html'>&lt;blockquote&gt;&lt;p&gt;Emancipate yourself from mental slavery, none but ourselves can free our minds. --Bob Marley, Redemption Song&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;There are a number of reasons to love Ruby and I will share some of them here. Ruby is influenced by some of the greatest languages ever invented: Perl, probably the most pragmatic language in the world, hell, even God used it :)&lt;/p&gt;

&lt;p&gt;&lt;img src="http://imgs.xkcd.com/comics/lisp.jpg" alt="Lisp from XKCD" /&gt;&lt;/p&gt;

&lt;p&gt;Ruby is also influenced by Smalltalk and Lisp. Both these languages are still living, vibrant languages despite their respectable age, 40 and 60 years respectively.&lt;/p&gt;

&lt;p&gt;When Matz chose parts from the above programming languages his primary design goal was &lt;strong&gt;Programmer Happiness&lt;/strong&gt;. He succeeded.&lt;/p&gt;

&lt;p&gt;Here are some features that I love about the language.&lt;/p&gt;

&lt;h2&gt;Parallel Assignment&lt;/h2&gt;

&lt;p&gt;You can assign many values on the same line by separating them by commas. They are assigned in parallel. No need for temporary variables.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Swap a and b, without a temporary variable&lt;/font&gt;&lt;/i&gt;
a&lt;font color="#990000"&gt;,&lt;/font&gt; b &lt;font color="#990000"&gt;=&lt;/font&gt; b&lt;font color="#990000"&gt;,&lt;/font&gt; a
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Multiple Return Values&lt;/h2&gt;

&lt;p&gt;If you want to return more than one value in Ruby all you need to do is to wrap it in an array. Then you can get the values by using commas. Also note, that return is not required in Ruby, the last evaluated expression is returned.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; div&lt;font color="#990000"&gt;(&lt;/font&gt;a&lt;font color="#990000"&gt;,&lt;/font&gt; b&lt;font color="#990000"&gt;)&lt;/font&gt;
  &lt;font color="#990000"&gt;[&lt;/font&gt;a&lt;font color="#990000"&gt;/&lt;/font&gt;b&lt;font color="#990000"&gt;,&lt;/font&gt; a&lt;font color="#990000"&gt;%&lt;/font&gt;b&lt;font color="#990000"&gt;]&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

a&lt;font color="#990000"&gt;,&lt;/font&gt; b &lt;font color="#990000"&gt;=&lt;/font&gt; div&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;5&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# a = 2, b = 1&lt;/font&gt;&lt;/i&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;String Interpolation&lt;/h2&gt;

&lt;p&gt;Double-quoted strings can be interpolated.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;kid &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;'Kid'&lt;/font&gt;
&lt;font color="#FF0000"&gt;"Hello #{kid} ##{1+3}"&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; Hello Kid #4&lt;/font&gt;&lt;/i&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Here documents&lt;/h2&gt;

&lt;p&gt;You have seen them in other scripting languages and they are as good as they look. No need for String concatenation or embedded newlines (\n).&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;sql &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;&amp;lt;&amp;lt;-&lt;/font&gt;SQL
SELECT allocations&lt;font color="#990000"&gt;.&lt;/font&gt;project_id as project_id&lt;font color="#990000"&gt;,&lt;/font&gt; year&lt;font color="#990000"&gt;,&lt;/font&gt; week&lt;font color="#990000"&gt;,&lt;/font&gt; allocations&lt;font color="#990000"&gt;.&lt;/font&gt;id as allocation_id
  FROM weeks
  LEFT OUTER JOIN allocations ON allocations&lt;font color="#990000"&gt;.&lt;/font&gt;start_date &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; weeks&lt;font color="#990000"&gt;.&lt;/font&gt;end_date
    AND allocations&lt;font color="#990000"&gt;.&lt;/font&gt;end_date &lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; weeks&lt;font color="#990000"&gt;.&lt;/font&gt;start_date
    AND allocations&lt;font color="#990000"&gt;.&lt;/font&gt;project_id &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;?&lt;/font&gt;
  WHERE weeks&lt;font color="#990000"&gt;.&lt;/font&gt;start_date &lt;font color="#990000"&gt;&amp;gt;=&lt;/font&gt; &lt;font color="#990000"&gt;?&lt;/font&gt; AND weeks&lt;font color="#990000"&gt;.&lt;/font&gt;end_date &lt;font color="#990000"&gt;&amp;lt;=&lt;/font&gt; &lt;font color="#990000"&gt;?&lt;/font&gt;
SQL
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Higher Order Functions&lt;/h2&gt;

&lt;p&gt;Higher order functions are easily expressed with Ruby blocks.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Map converts an array of values to a new array of values&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#FF0000"&gt;"a"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"b"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"c"&lt;/font&gt;&lt;font color="#990000"&gt;].&lt;/font&gt;map &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;item&lt;font color="#990000"&gt;|&lt;/font&gt; item&lt;font color="#990000"&gt;.&lt;/font&gt;upcase &lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; ["A", "B", "C"]&lt;/font&gt;&lt;/i&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Zip zips arrays together&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;].&lt;/font&gt;zip&lt;font color="#990000"&gt;([&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;20&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;30&lt;/font&gt;&lt;font color="#990000"&gt;])&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; [[1, 10], [2, 20], [3, 30]]&lt;/font&gt;&lt;/i&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Zip with a function applies the function to the results&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;3&lt;/font&gt;&lt;font color="#990000"&gt;].&lt;/font&gt;zip&lt;font color="#990000"&gt;([&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;20&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;30&lt;/font&gt;&lt;font color="#990000"&gt;])&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#990000"&gt;|&lt;/font&gt;arr&lt;font color="#990000"&gt;|&lt;/font&gt; arr&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;+&lt;/font&gt; arr&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; [11, 22, 33]&lt;/font&gt;&lt;/i&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Simple Command Line Access&lt;/h2&gt;

&lt;p&gt;The command line is always readily available in Ruby&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Backticks invokes the command and returns the result as a string&lt;/font&gt;&lt;/i&gt;
`ls`
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; "Scripts\nStylesheets\nbin\nget_destinations.scpt\nlib\nnibs\n"&lt;/font&gt;&lt;/i&gt;
`ls`&lt;font color="#990000"&gt;.&lt;/font&gt;split
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; ["Scripts", "Stylesheets", "bin", "get_destinations.scpt", "lib", "nibs"]&lt;/font&gt;&lt;/i&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# System invokes the command, prints the result to stdout, and return a boolean&lt;/font&gt;&lt;/i&gt;
system&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'ls -l'&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
total &lt;font color="#993399"&gt;64&lt;/font&gt;
drwxr&lt;font color="#990000"&gt;-&lt;/font&gt;xr&lt;font color="#990000"&gt;-&lt;/font&gt;x  &lt;font color="#993399"&gt;3&lt;/font&gt; andersjanmyr  admin    &lt;font color="#993399"&gt;102&lt;/font&gt; Aug &lt;font color="#993399"&gt;29&lt;/font&gt;  &lt;font color="#993399"&gt;2009&lt;/font&gt; Scripts
drwxr&lt;font color="#990000"&gt;-&lt;/font&gt;xr&lt;font color="#990000"&gt;-&lt;/font&gt;x  &lt;font color="#993399"&gt;3&lt;/font&gt; andersjanmyr  admin    &lt;font color="#993399"&gt;102&lt;/font&gt; Aug &lt;font color="#993399"&gt;29&lt;/font&gt;  &lt;font color="#993399"&gt;2009&lt;/font&gt; Stylesheets
drwxr&lt;font color="#990000"&gt;-&lt;/font&gt;xr&lt;font color="#990000"&gt;-&lt;/font&gt;x  &lt;font color="#993399"&gt;5&lt;/font&gt; andersjanmyr  admin    &lt;font color="#993399"&gt;170&lt;/font&gt; Aug &lt;font color="#993399"&gt;29&lt;/font&gt;  &lt;font color="#993399"&gt;2009&lt;/font&gt; bin
&lt;font color="#990000"&gt;-&lt;/font&gt;rw&lt;font color="#990000"&gt;-&lt;/font&gt;r&lt;font color="#990000"&gt;--&lt;/font&gt;r&lt;font color="#990000"&gt;--&lt;/font&gt;  &lt;font color="#993399"&gt;1&lt;/font&gt; andersjanmyr  admin  &lt;font color="#993399"&gt;12312&lt;/font&gt; Aug &lt;font color="#993399"&gt;29&lt;/font&gt;  &lt;font color="#993399"&gt;2009&lt;/font&gt; get_destinations&lt;font color="#990000"&gt;.&lt;/font&gt;scpt
drwxr&lt;font color="#990000"&gt;-&lt;/font&gt;xr&lt;font color="#990000"&gt;-&lt;/font&gt;x  &lt;font color="#993399"&gt;3&lt;/font&gt; andersjanmyr  admin    &lt;font color="#993399"&gt;102&lt;/font&gt; Aug &lt;font color="#993399"&gt;29&lt;/font&gt;  &lt;font color="#993399"&gt;2009&lt;/font&gt; lib
drwxr&lt;font color="#990000"&gt;-&lt;/font&gt;xr&lt;font color="#990000"&gt;-&lt;/font&gt;x  &lt;font color="#993399"&gt;3&lt;/font&gt; andersjanmyr  admin    &lt;font color="#993399"&gt;102&lt;/font&gt; Aug &lt;font color="#993399"&gt;29&lt;/font&gt;  &lt;font color="#993399"&gt;2009&lt;/font&gt; nibs
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; true&lt;/font&gt;&lt;/i&gt;

system&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'ls tapir'&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
ls&lt;font color="#990000"&gt;:&lt;/font&gt; tapir&lt;font color="#990000"&gt;:&lt;/font&gt; No such file &lt;b&gt;&lt;font color="#0000FF"&gt;or&lt;/font&gt;&lt;/b&gt; directory
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; false&lt;/font&gt;&lt;/i&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Open Classes&lt;/h2&gt;

&lt;p&gt;Open classes mean that it is possible to add new methods to already existing classes. This is very powerful.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; String
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; vowels
    &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;scan&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF6600"&gt;/[aeiouy]/&lt;/font&gt;i&lt;font color="#990000"&gt;)&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;font color="#FF0000"&gt;"A tapir is beautiful"&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;vowels
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; ["A", "a", "i", "i", "e", "a", "u", "i", "u"]&lt;/font&gt;&lt;/i&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;There are two common reactions to this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wow! This is really cool, this will allow me to put everything in the right place.&lt;/li&gt;
&lt;li&gt;What! That is too dangerous, our programmers will create an unmaintainable system.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I'm in the first camp!&lt;/p&gt;

&lt;h2&gt;Class Inheritance&lt;/h2&gt;

&lt;p&gt;In Ruby the classes are objects and follow the inheritance rules of objects. No statics are needed.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Mammal
  &lt;i&gt;&lt;font color="#9A1900"&gt;# This is a class method, that returns all mammals of this kind&lt;/font&gt;&lt;/i&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;all
    mammals&lt;font color="#990000"&gt;.&lt;/font&gt;select &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;m&lt;font color="#990000"&gt;|&lt;/font&gt;
      m&lt;font color="#990000"&gt;.&lt;/font&gt;kind_of? &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  &lt;i&gt;&lt;font color="#9A1900"&gt;# Another class method that gives access to the class varibable&lt;/font&gt;&lt;/i&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;self&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;mammals
    &lt;i&gt;&lt;font color="#9A1900"&gt;# @@ is a class variable prefix&lt;/font&gt;&lt;/i&gt;
    &lt;font color="#009900"&gt;@@all_mammals&lt;/font&gt; &lt;font color="#990000"&gt;||=&lt;/font&gt; &lt;font color="#990000"&gt;[]&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Tapir &lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt; Mammal
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Add some mammals and a tapir&lt;/font&gt;&lt;/i&gt;
Mammal&lt;font color="#990000"&gt;.&lt;/font&gt;mammals &lt;font color="#990000"&gt;&amp;lt;&amp;lt;&lt;/font&gt; Mammal&lt;font color="#990000"&gt;.&lt;/font&gt;new &lt;font color="#990000"&gt;&amp;lt;&amp;lt;&lt;/font&gt; Mammal&lt;font color="#990000"&gt;.&lt;/font&gt;new &lt;font color="#990000"&gt;&amp;lt;&amp;lt;&lt;/font&gt; Tapir&lt;font color="#990000"&gt;.&lt;/font&gt;new

Tapir&lt;font color="#990000"&gt;.&lt;/font&gt;all
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; [#&amp;lt;Tapir:0x000001010fc1a0&amp;gt;]&lt;/font&gt;&lt;/i&gt;

Mammal&lt;font color="#990000"&gt;.&lt;/font&gt;all
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; [#&amp;lt;Mammal:0x000001010fc218&amp;gt;, #&amp;lt;Mammal:0x000001010fc1c8&amp;gt;, #&amp;lt;Tapir:0x000001010fc1a0&amp;gt;]&lt;/font&gt;&lt;/i&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2&gt;Meta Programming&lt;/h2&gt;

&lt;p&gt;When the classes are parsed, Ruby is already running and since it is possible to create methods and classes on the fly you can do some very powerful meta-programming with Ruby. Here is a simple example.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Tapir

  &lt;font color="#990000"&gt;[:&lt;/font&gt;sniff&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;eat&lt;font color="#990000"&gt;].&lt;/font&gt;each &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;method_name&lt;font color="#990000"&gt;|&lt;/font&gt;
    send &lt;font color="#990000"&gt;:&lt;/font&gt;define_method&lt;font color="#990000"&gt;,&lt;/font&gt; method_name &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;|&lt;/font&gt;thing&lt;font color="#990000"&gt;|&lt;/font&gt;
      &lt;font color="#FF0000"&gt;"I'm #{method_name}ing #{thing}!"&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;


t &lt;font color="#990000"&gt;=&lt;/font&gt; Tapir&lt;font color="#990000"&gt;.&lt;/font&gt;new
t&lt;font color="#990000"&gt;.&lt;/font&gt;eat &lt;font color="#FF0000"&gt;'bananas'&lt;/font&gt;
I'm eating bananas!

t&lt;font color="#990000"&gt;.&lt;/font&gt;sniff &lt;font color="#FF0000"&gt;'glue'&lt;/font&gt;
I'm sniffing glue!

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This type of meta-programming is what enables the simplicity of Rails' &lt;code&gt;has_many&lt;/code&gt;, and &lt;code&gt;belongs_to&lt;/code&gt; methods for declaring relationships.&lt;/p&gt;

&lt;h2&gt;Method Missing&lt;/h2&gt;

&lt;p&gt;The last feature of Ruby that I want to share is &lt;code&gt;method_missing&lt;/code&gt;. &lt;code&gt;method_missing&lt;/code&gt; is a feature that Ruby inherited from Smalltalk. If an object is invoked with a method that is not defined by its class or ancestors, &lt;code&gt;method_missing(method, args)&lt;/code&gt; is called instead. By implementing this method you can effectively create all sorts of cool stuff such as proxies, prototypes, etc.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Simple implementation of a Javascript-like structure without inheritance&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; Prototype

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; props
    &lt;font color="#009900"&gt;@props&lt;/font&gt; &lt;font color="#990000"&gt;||=&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; method_missing&lt;font color="#990000"&gt;(&lt;/font&gt;method&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt;args&lt;font color="#990000"&gt;)&lt;/font&gt;
    m &lt;font color="#990000"&gt;=&lt;/font&gt; method&lt;font color="#990000"&gt;.&lt;/font&gt;to_s&lt;font color="#990000"&gt;.&lt;/font&gt;sub&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'='&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;''&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;# Strip the trailing '=' to allow setters&lt;/font&gt;&lt;/i&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; args&lt;font color="#990000"&gt;.&lt;/font&gt;empty?
      props&lt;font color="#990000"&gt;[&lt;/font&gt;m&lt;font color="#990000"&gt;]&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;else&lt;/font&gt;&lt;/b&gt;
      props&lt;font color="#990000"&gt;[&lt;/font&gt;m&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; args&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

prot &lt;font color="#990000"&gt;=&lt;/font&gt; Prototype&lt;font color="#990000"&gt;.&lt;/font&gt;new
prot&lt;font color="#990000"&gt;.&lt;/font&gt;age
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; nil&lt;/font&gt;&lt;/i&gt;
prot&lt;font color="#990000"&gt;.&lt;/font&gt;age &lt;font color="#993399"&gt;14&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; 14&lt;/font&gt;&lt;/i&gt;
prot&lt;font color="#990000"&gt;.&lt;/font&gt;age
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; 14&lt;/font&gt;&lt;/i&gt;
prot&lt;font color="#990000"&gt;.&lt;/font&gt;age&lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;16&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; 16&lt;/font&gt;&lt;/i&gt;
prot&lt;font color="#990000"&gt;.&lt;/font&gt;age
&lt;i&gt;&lt;font color="#9A1900"&gt;# =&amp;gt; 16&lt;/font&gt;&lt;/i&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Inside &lt;code&gt;method_missing&lt;/code&gt; it is of course also possible to define new methods and classes dynamically, but I'll leave that for another day.&lt;/p&gt;

&lt;p&gt;Ruby is a supreme dynamic language that lets you do almost anything. Try it!&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;When you can do anything, you have to become more responsible. You own your fate. And, that, I think, is a situation which promotes responsibility. -- Michael Feathers, author of &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052?tag=thtasta-20"&gt;Working Effectively with Legacy Code&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-7010963155504705942?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/7010963155504705942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=7010963155504705942' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7010963155504705942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/7010963155504705942'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/09/why-ruby.html' title='Why Ruby?'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-4596991276558819123</id><published>2010-09-22T09:45:00.001+02:00</published><updated>2010-09-22T09:45:00.579+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>Javascript, the Interlingua of the Web, Karlskrona</title><content type='html'>&lt;p&gt;Links and Books from my Javascript presentation in Karlskrona.&lt;/p&gt;

&lt;h2&gt;The Y Combinator&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.dreamsongs.com/Files/WhyOfY.pdf"&gt;The Why of Y(PDF)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html"&gt;The Y Combinator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://kestas.kuliukas.com/YCombinatorExplained/"&gt;The Y Combinator in Javascript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Books&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Little-Schemer-Daniel-P-Friedman/dp/0262560992?tag=thtasta-20"&gt;The Little Schemer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742?tag=thtasta-20"&gt;Javascript, the Good Parts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/jQuery-Cookbook-Solutions-Examples-Developers/dp/0596159773?tag=thtasta-20"&gt;jQuery Cookbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/jQuery-Action-Second-Bear-Bibeault/dp/1935182323?tag=thtasta-20"&gt;jQuery in Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Handcrafted-CSS-More-Bulletproof-Design/dp/0321643380?tag=thtasta-20"&gt;Handcrafted CSS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Tools&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://dl.dropbox.com/u/7283184/jquery-api-1.4.2.html"&gt;My View of the jQuery API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://codylindley.com/jqueryselectors/"&gt;JQuery Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.crockford.com/javascript/jsmin.html"&gt;JsMin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;YUI Compressor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://xrefresh.binaryage.com/"&gt;XRefresh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/mockko/livereload"&gt;LiveReload&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/mynyml/watchr"&gt;Watchr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.scons.org/"&gt;SCons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-4596991276558819123?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/4596991276558819123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=4596991276558819123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4596991276558819123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4596991276558819123'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/09/javascript-interlingua-of-web.html' title='Javascript, the Interlingua of the Web, Karlskrona'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-3578433267991975433</id><published>2010-09-18T08:00:00.002+02:00</published><updated>2011-04-07T09:53:15.367+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='css webkit'/><title type='text'>Webkit CSS Transitions and Transformations</title><content type='html'>&lt;p&gt;This blog is best viewed in Safari or Chrome since it uses Webkit-specific functionality.&lt;/p&gt;

&lt;h2&gt;Transitions&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;transition&lt;/strong&gt;, the process or a period of changing from one state or condition to another&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Transitions are usually performed using jQuery or some other Javascript framework to animate the changes to a property. When using Webkit (Safari, Chrome, iPad, iPhone) Javascript is not necessary anymore.&lt;/p&gt;

&lt;p&gt;In Webkit the transitions are described using four different properties. It is worth noting that the properties only define how the transitions will work when the values on the element is changed. &lt;em&gt;They don't actually do anything until the values are changed!&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;/* This sets up a transition property on all divs on opacity.*/&lt;/font&gt;&lt;/i&gt;
div &lt;font color="#FF0000"&gt;{&lt;/font&gt;
  &lt;font color="#0000FF"&gt;-webkit-transition-property:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;opacity&lt;/font&gt;&lt;/i&gt;;
  &lt;font color="#0000FF"&gt;-webkit-transition-duration:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;2s&lt;/font&gt;&lt;/i&gt;;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;/* The fade-in class, changes the opacity when set on an element.&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;  And thus triggers the transition defined above if the element is a div. */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#993399"&gt;.fade&lt;/font&gt;&lt;font color="#990000"&gt;-&lt;/font&gt;in &lt;font color="#FF0000"&gt;{&lt;/font&gt;
  &lt;font color="#0000FF"&gt;opacity:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;1&lt;/font&gt;&lt;/i&gt;;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Adds the class 'fade-in' on all divs, via jQuery.&lt;/font&gt;&lt;/i&gt;
$&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"div"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;each&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
  $&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;addClass&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'fade-in'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h3&gt;&lt;code&gt;-webkit-transition-property&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;This is the property that will be affected by the transition, this can be any valid property, and it defaults to &lt;strong&gt;all&lt;/strong&gt;. What this means is that a change to any attribute on an element will be affected by the transition and occur according to the specification.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;/* only width should be affected */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;property&lt;font color="#990000"&gt;:&lt;/font&gt; width&lt;font color="#990000"&gt;;&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;/* multiple comma-separated properties are supported */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;property&lt;font color="#990000"&gt;:&lt;/font&gt; opacity&lt;font color="#990000"&gt;,&lt;/font&gt; width&lt;font color="#990000"&gt;,&lt;/font&gt; height&lt;font color="#990000"&gt;;&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;/* all properties should be affected, this is the default */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;property&lt;font color="#990000"&gt;:&lt;/font&gt; all&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h3&gt;&lt;code&gt;-webkit-transition-duration&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;How long the transition should take? Valid units are &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;ms&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;/* Set the duration to 400 milliseconds */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;duration&lt;font color="#990000"&gt;:&lt;/font&gt; 400ms&lt;font color="#990000"&gt;;&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;/* Multiple values are supported here too, in combination with&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;multiple -webkit-transition-property's */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;property&lt;font color="#990000"&gt;:&lt;/font&gt; opacity&lt;font color="#990000"&gt;,&lt;/font&gt; width&lt;font color="#990000"&gt;,&lt;/font&gt; height&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;duration&lt;font color="#990000"&gt;:&lt;/font&gt; 400ms, 1s, 3s&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h3&gt;&lt;code&gt;-webkit-transition-delay&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;How long should we wait before the transition starts. Valid units are &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;ms&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;/* Set the delay to 1 second */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;delay&lt;font color="#990000"&gt;:&lt;/font&gt; 1s&lt;font color="#990000"&gt;;&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;/* Multiple values are supported here too, in combination with&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;multiple -webkit-transition-property's */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;property&lt;font color="#990000"&gt;:&lt;/font&gt; width&lt;font color="#990000"&gt;,&lt;/font&gt; height&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;delay&lt;font color="#990000"&gt;:&lt;/font&gt; 1s, 3s&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h3&gt;&lt;code&gt;-webkit-transition-timing-function&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;The timing function is a function that changes the speed of the transition over its duration. It is described with a &lt;a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve"&gt;cubic-bezier&lt;/a&gt; curve, but it has some predefined values, &lt;code&gt;ease&lt;/code&gt; (default), &lt;code&gt;ease-in&lt;/code&gt;, &lt;code&gt;ease-out&lt;/code&gt;, &lt;code&gt;ease-in-out&lt;/code&gt;, and &lt;code&gt;linear&lt;/code&gt;. In none of those values are to your liking you can define your own with the &lt;code&gt;cubic-bezier&lt;/code&gt; function.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;/* Transition with the default timing*/&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;timing&lt;font color="#990000"&gt;-&lt;/font&gt;function&lt;font color="#990000"&gt;:&lt;/font&gt; ease&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;/* Multiple values are supported here too, in combination with&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;multiple -webkit-transition-property's */&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;property&lt;font color="#990000"&gt;:&lt;/font&gt; opacity&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transform&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;font color="#990000"&gt;-&lt;/font&gt;webkit&lt;font color="#990000"&gt;-&lt;/font&gt;transition&lt;font color="#990000"&gt;-&lt;/font&gt;timing&lt;font color="#990000"&gt;-&lt;/font&gt;function&lt;font color="#990000"&gt;:&lt;/font&gt; ease&lt;font color="#990000"&gt;-&lt;/font&gt;out&lt;font color="#990000"&gt;,&lt;/font&gt; cubic&lt;font color="#990000"&gt;-&lt;/font&gt;bezier&lt;font color="#990000"&gt;(&lt;/font&gt;0&lt;font color="#993399"&gt;.5&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 0&lt;font color="#993399"&gt;.2&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 0&lt;font color="#993399"&gt;.3&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; 1&lt;font color="#993399"&gt;.0&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Thats it for transitions. But wait, what was that &lt;code&gt;-webkit-transform&lt;/code&gt; in the end?&lt;/p&gt;

&lt;h2&gt;Transformations&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;transformation&lt;/strong&gt;, a thorough or dramatic change in form or appearance&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Webkit supports some really cool transformations, that allow you to animate the pages in remarkable ways.&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;rotate()&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;style&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt; "width: 12em;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  margin-top: 5em;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  -webkit-transform: rotate(45deg)"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
I am rotated!
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;


&lt;div style = "width: 12em;
  margin-top: 5em;
  -webkit-transform: rotate(45deg)"&gt;
I am rotated!
&lt;/div&gt;


&lt;p&gt;Rotate accepts the units &lt;code&gt;deg&lt;/code&gt;, &lt;code&gt;rad&lt;/code&gt;, and &lt;code&gt;grad&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It also comes in 3D forms, &lt;code&gt;rotateX&lt;/code&gt;, &lt;code&gt;rotateY&lt;/code&gt;, &lt;code&gt;rotateZ&lt;/code&gt;, and &lt;code&gt;rotate3d&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;scale()&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;style&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt; "width: 12em;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  margin: 2em 0 2em 18em;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  -webkit-transform: scale(4)"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
I am Scaled!
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;


&lt;div style = "width: 12em;
  margin: 2em 0 2em 18em;
  -webkit-transform: scale(4)"&gt;
I am Scaled!
&lt;/div&gt;


&lt;p&gt;Scale can take an additional parameter &lt;code&gt;scale(x, y)&lt;/code&gt; If you want to scale  un-proportionally. It also comes in 3D versions, &lt;code&gt;scaleX&lt;/code&gt;, &lt;code&gt;scaleY&lt;/code&gt;, &lt;code&gt;scaleZ&lt;/code&gt;, and &lt;code&gt;scale3d&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;translate()&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;style&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt; "width: 12em;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  margin: 2em;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  -webkit-transform: translate(4em, -2em)"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
I am Translated!
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;


&lt;div style = "width: 12em;
  margin: 2em;
  -webkit-transform: translate(4em, -2em)"&gt;
I am Translated!
&lt;/div&gt;


&lt;p&gt;Translate takes one or two parameters and moves the element to the new location. It, too, comes in 3D forms, &lt;code&gt;translateX&lt;/code&gt;, &lt;code&gt;translateY&lt;/code&gt;, &lt;code&gt;translateZ&lt;/code&gt;, and &lt;code&gt;translate3d&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Additional Transforms&lt;/h3&gt;

&lt;p&gt;Apart from the translations above, Webkit also supports &lt;code&gt;skew&lt;/code&gt;, &lt;code&gt;perspective&lt;/code&gt;, and &lt;code&gt;matrix&lt;/code&gt;. Read more in &lt;a href="http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariCSSRef/Articles/Functions.html#//apple_ref/doc/uid/TP40007955-SW22"&gt;the Safari Reference Library&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll finish up with a composite transform combined with transitions, best viewed with Safari. This transformations are initiated by changing the style from Javascript.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;style&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"width: 4em; height: 4em;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  margin: 2em; background-color: blue;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  color: white;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  -webkit-transition-duration: 5s;&lt;/font&gt;
&lt;font color="#FF0000"&gt;  -webkit-transition-function: ease-out;"&lt;/font&gt;
  &lt;font color="#009900"&gt;onclick&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;'style.webkitTransform="translate(16em, -16em) scale(6) rotate(720deg)"; style.backgroundColor="red";'&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt; Click Me!
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;


&lt;div style="width: 4em; height: 4em;
  margin: 2em; background-color: blue;
  color: white;
  -webkit-transition-duration: 5s;
  -webkit-transition-function: ease-out;"
  onclick='style.webkitTransform="translate(16em, -16em) scale(6) rotate(720deg)"; style.backgroundColor="red";'&gt; Click Me!
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-3578433267991975433?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/3578433267991975433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=3578433267991975433' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/3578433267991975433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/3578433267991975433'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/09/webkit-css-transitions-and.html' title='Webkit CSS Transitions and Transformations'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-3135050214104601508</id><published>2010-09-02T09:42:00.000+02:00</published><updated>2010-09-02T09:42:45.395+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Using Git with Subversion</title><content type='html'>&lt;p&gt;I had the unfortunate experience of having to use Subversion again after using Git for a long time. It is amazing how fast I can forget. After renaming a directory at the prompt, and the agony that goes with it, I decided to switch back to Git.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;$ mv requester sampler
&lt;i&gt;&lt;font color="#9A1900"&gt;# svn agony after renaming a directory&lt;/font&gt;&lt;/i&gt;
$ svn st
&lt;font color="#990000"&gt;?&lt;/font&gt;       sampler
&lt;font color="#990000"&gt;!&lt;/font&gt;       requester
&lt;font color="#990000"&gt;!&lt;/font&gt;       requester&lt;font color="#990000"&gt;.&lt;/font&gt;rb
A       sampler&lt;font color="#990000"&gt;.&lt;/font&gt;rb

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;The tool to use when using Git with Subversion is, of course, &lt;code&gt;git svn&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git svn&lt;/code&gt; works very well as long as you remember that &lt;em&gt;Subversion is not Git&lt;/em&gt;. It does not handle merging well, and it will bite you if you don't respect that. So what does this actually mean? It means:&lt;/p&gt;

&lt;h2&gt;Always keep the Git master in sync with Subversion&lt;/h2&gt;

&lt;p&gt;To do this you have two commands you can use.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Rebases the commits from the upstream Subversion server with your local master.&lt;/font&gt;&lt;/i&gt;
$ git svn rebase

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;You should only &lt;code&gt;git svn rebase&lt;/code&gt; in your Git master, and you should &lt;strong&gt;ALWAYS&lt;/strong&gt; do it before you &lt;code&gt;git svn dcommit&lt;/code&gt; anything to the subversion repository. &lt;code&gt;git svn rebase&lt;/code&gt; keeps the upstream subversion in sync with your local master by pulling down the changes, kind of like &lt;code&gt;svn update&lt;/code&gt;.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Commits the changes you have in your local master to the upstream Subversion server.&lt;/font&gt;&lt;/i&gt;
$ git svn dcommit

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;When you have changes ready to commit, you commit them to subversion with &lt;code&gt;git svn dcommit&lt;/code&gt;. You should &lt;strong&gt;ALWAYS&lt;/strong&gt; &lt;code&gt;git svn rebase&lt;/code&gt; before you do the update, or it will fail.&lt;/p&gt;

&lt;p&gt;That's it! As long as you follow these two simple rules, your life with &lt;code&gt;git svn&lt;/code&gt; will be easy. If you forget to follow them, you will be bitten. When you get bitten, the cool thing about Git is that even if you screw up, it is always possible to sort it out.&lt;/p&gt;

&lt;p&gt;It that was all there was to it, there would be no reason to use Git instead of Subversion. Git really shines when it comes to branching and merging. You may create as many local branches as you like with &lt;code&gt;git branch branch_name&lt;/code&gt; or &lt;code&gt;git checkout -b branch_name&lt;/code&gt;. You can hack around in these local branches as much as you want and merge them together. But, before you merge them into the master branch, &lt;strong&gt;you must rebase with master! Not merge, rebase!&lt;/strong&gt; Rebase means replay the commits on top of the named branch. It creates new commits, the same content, but with a different SHA-1.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Example session&lt;/font&gt;&lt;/i&gt;

&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn rebase
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout -b dev
hack&lt;font color="#990000"&gt;,&lt;/font&gt; hack&lt;font color="#990000"&gt;,&lt;/font&gt; hack&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;...&lt;/font&gt;
&lt;font color="#990000"&gt;(&lt;/font&gt;dev&lt;font color="#990000"&gt;)&lt;/font&gt;$ git commit -am &lt;font color="#FF0000"&gt;'Commit the changes'&lt;/font&gt; 

&lt;font color="#990000"&gt;(&lt;/font&gt;dev&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout master
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout -b bugfix
hack&lt;font color="#990000"&gt;,&lt;/font&gt; hack&lt;font color="#990000"&gt;,&lt;/font&gt; hack&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;...,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;done&lt;/font&gt;&lt;/b&gt;

&lt;font color="#990000"&gt;(&lt;/font&gt;bugfix&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout master
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn rebase
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout bugfix
$ git rebase master
&lt;font color="#990000"&gt;(&lt;/font&gt;bugfix&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout master
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git merge --ff bugfix &lt;i&gt;&lt;font color="#9A1900"&gt;# --ff only fast-forwards, merges that don't need to merge. &lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn dcommit
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git branch -D bugfix &lt;i&gt;&lt;font color="#9A1900"&gt;# delete the branch it is not needed anymore&lt;/font&gt;&lt;/i&gt;

&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout dev
hack&lt;font color="#990000"&gt;,&lt;/font&gt; hack&lt;font color="#990000"&gt;,&lt;/font&gt; hack&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;...,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;done&lt;/font&gt;&lt;/b&gt;

&lt;font color="#990000"&gt;(&lt;/font&gt;dev&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout master
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn rebase
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout dev
&lt;font color="#990000"&gt;(&lt;/font&gt;dev&lt;font color="#990000"&gt;)&lt;/font&gt;$ git rebase master
&lt;font color="#990000"&gt;(&lt;/font&gt;dev&lt;font color="#990000"&gt;)&lt;/font&gt;$ git checkout master
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git merge --ff dev &lt;i&gt;&lt;font color="#9A1900"&gt;# --ff only fast-forwards, merges that don't need to merge.&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn dcommit

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Another thing to be aware of is that &lt;code&gt;git svn dcommit&lt;/code&gt; creates an extra commit, so even if you haven't changed anything in the master you need to rebase the local branch with the master. This is only needed if you don't delete the branches after you are done with a commit.&lt;/p&gt;

&lt;p&gt;In the example above, I ended with a &lt;code&gt;git svn dcommit&lt;/code&gt; and I didn't remove the &lt;code&gt;dev&lt;/code&gt; branch.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn dcommit &lt;i&gt;&lt;font color="#9A1900"&gt;# from above&lt;/font&gt;&lt;/i&gt;
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git co dev
&lt;font color="#990000"&gt;(&lt;/font&gt;dev&lt;font color="#990000"&gt;)&lt;/font&gt;$ git rebase master &lt;i&gt;&lt;font color="#9A1900"&gt;# rebases the extra commit created by git svn dcommit&lt;/font&gt;&lt;/i&gt;

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;If you forget to rebase or something else happens that hinders a clean merge into the master. You can always back out of it with &lt;code&gt;git reset --hard&lt;/code&gt;.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn dcommit
&lt;font color="#990000"&gt;...&lt;/font&gt; failed miserably&lt;font color="#990000"&gt;,&lt;/font&gt; because I failed to git svn rebase&lt;font color="#990000"&gt;,&lt;/font&gt; bollocks&lt;font color="#990000"&gt;!&lt;/font&gt;
&lt;font color="#990000"&gt;(&lt;/font&gt;aa&lt;font color="#990000"&gt;..&lt;/font&gt;88dd&lt;font color="#990000"&gt;|&lt;/font&gt;MERGING&lt;font color="#990000"&gt;)&lt;/font&gt;$ git reset --hard
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn rebase
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git svn dcommit &lt;i&gt;&lt;font color="#9A1900"&gt;# Nice and clean commit&lt;/font&gt;&lt;/i&gt;

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;To get started you need to clone a subversion repository.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;$ git svn clone http&lt;font color="#990000"&gt;:&lt;/font&gt;//svn&lt;font color="#990000"&gt;.&lt;/font&gt;example&lt;font color="#990000"&gt;.&lt;/font&gt;com/project/trunk
$ cd trunk
&lt;font color="#990000"&gt;(&lt;/font&gt;master&lt;font color="#990000"&gt;)&lt;/font&gt;$ git &lt;font color="#990000"&gt;...&lt;/font&gt;

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Now, is a good time to start using Git. Get yourself anything by Scott Chacon, such as the &lt;a href="http://www.amazon.com/Pro-Git-Scott-Chacon/dp/1430218339?tag=thtasta-20"&gt;book&lt;/a&gt; or the &lt;a href="http://www.gitcasts.com/"&gt;screencasts&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-3135050214104601508?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/3135050214104601508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=3135050214104601508' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/3135050214104601508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/3135050214104601508'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/09/using-git-with-subversion.html' title='Using Git with Subversion'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-4085668590060450928</id><published>2010-08-26T15:09:00.000+02:00</published><updated>2010-08-26T15:09:55.866+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>The Ruby Toolbox</title><content type='html'>&lt;p&gt;One of the great things about Ruby is the community. When something is not working out as well as it could, someone figures out a way to improve it.&lt;/p&gt;

&lt;p&gt;It used to be difficult to select what gems, Ruby libraries, to use when solving a task that I was  not familiar with. This is not the case anymore.
&lt;a href="http://colszowka.heroku.com"&gt;Christoph Olszowka&lt;/a&gt; decided that he wanted to solve this problem and created &lt;a href="http://ruby-toolbox.com/"&gt;The Ruby Toolbox&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;a href="http://ruby-toolbox.com/"&gt;The Ruby Toolbox&lt;/a&gt;, &lt;strong&gt;Know your options!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ruby developers can choose from a variety of tools to get their job done.&lt;/p&gt;

&lt;p&gt;The Ruby Toolbox gives you an overview of these tools, sorted in categories and rated by the amount of watchers and forks in the corresponding source code repository on GitHub so you can find out easily what options you have and which are the most common ones in the Ruby community.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This is surprisingly powerful. In my latest project I used the following libraries (among others).&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://ruby-toolbox.com/categories/web_app_frameworks.html#rails_rails"&gt;Rails&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Rails need no introduction, it is one of the best frameworks for creating dynamic web applications. With best, I mean most productive and fun to work with!&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://ruby-toolbox.com/categories/template_languages.html#nex3_haml"&gt;Haml&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML that's designed to express the structure of XHTML or XML documents in a non-repetitive, elegant, easy way!&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://www.ruby-toolbox.com/categories/http_clients.html#pauldix_typhoeus"&gt;Typhoeus&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Typhoeus is a http client library, a thick wrapper around curl, just like curl it works like a charm.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://www.ruby-toolbox.com/categories/deployment_automation.html#jamis_capistrano"&gt;Capistrano&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Ahh, Capistrano, deployment scripting done right! The simplicity of the structure is worth showing since it should be copied by other lesser tools.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Create the basic structure&lt;/font&gt;&lt;/i&gt;
$ cap deploy&lt;font color="#990000"&gt;:&lt;/font&gt;setup
mkdir -p /var/rails/rsvc 
/var/rails/rsvc/releases 
/var/rails/rsvc/shared 
&lt;font color="#990000"&gt;...&lt;/font&gt;

&lt;i&gt;&lt;font color="#9A1900"&gt;# Deploy from the repo into a timestamped release directory and symlink current&lt;/font&gt;&lt;/i&gt;
$ cap deploy
svn checkout -q  -r&lt;font color="#993399"&gt;5454&lt;/font&gt; https&lt;font color="#990000"&gt;:&lt;/font&gt;//svn&lt;font color="#990000"&gt;.&lt;/font&gt;neo4j&lt;font color="#990000"&gt;.&lt;/font&gt;org/qa/matrix-framework/rsvc/trunk/rsvc /var/rails/rsvc/releases&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;20100826122450&lt;/font&gt; 
echo &lt;font color="#993399"&gt;5454&lt;/font&gt; &lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; /var/rails/rsvc/releases&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;20100826122450&lt;/font&gt;/REVISION
&lt;font color="#990000"&gt;....&lt;/font&gt;
rm -f /var/rails/rsvc/current &lt;font color="#990000"&gt;&amp;amp;&amp;amp;&lt;/font&gt; ln -s /var/rails/rsvc/releases&lt;font color="#990000"&gt;/&lt;/font&gt;&lt;font color="#993399"&gt;20100826122450&lt;/font&gt; /var/rails/rsvc/current

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;It's so simple and powerful, that it makes me cry.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://www.ruby-toolbox.com/categories/server_monitoring.html#mojombo_god"&gt;God&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;God, a wonderfully named, server monitoring tool written in Ruby. God aims to be the simplest, most powerful monitoring application available.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://www.ruby-toolbox.com/categories/testing_frameworks.html#dchelimsky_rspec"&gt;RSpec&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;RSpec, only code can do it justice.&lt;/p&gt;
&lt;!-- Generator: GNU source-highlight 3.1.4
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite --&gt;
&lt;pre&gt;&lt;tt&gt;describe Request &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
  
  before &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
    &lt;font color="#009900"&gt;@sample&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; Sample&lt;font color="#990000"&gt;.&lt;/font&gt;create&lt;font color="#990000"&gt;(:&lt;/font&gt;name &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;'my_sample'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;method &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#FF0000"&gt;"post"&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
    
  context &lt;font color="#FF0000"&gt;'#old'&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
    it &lt;font color="#FF0000"&gt;"should not return any"&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
      Request&lt;font color="#990000"&gt;.&lt;/font&gt;old&lt;font color="#990000"&gt;.&lt;/font&gt;should be_empty
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
    &lt;font color="#990000"&gt;...&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

  context &lt;font color="#FF0000"&gt;'#delete_old_non_failing'&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;
  
    it &lt;font color="#FF0000"&gt;"should delete old non failing requests"&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;do&lt;/font&gt;&lt;/b&gt;      
      create_old_request &lt;font color="#990000"&gt;:&lt;/font&gt;response_status_code &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;
      create_old_request &lt;font color="#990000"&gt;:&lt;/font&gt;response_status_code &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#993399"&gt;200&lt;/font&gt;
      expect &lt;font color="#FF0000"&gt;{&lt;/font&gt;
        Request&lt;font color="#990000"&gt;.&lt;/font&gt;delete_old_non_failed
      &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;to change &lt;font color="#FF0000"&gt;{&lt;/font&gt; Request&lt;font color="#990000"&gt;.&lt;/font&gt;count &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;by&lt;font color="#990000"&gt;(-&lt;/font&gt;&lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
    &lt;font color="#990000"&gt;...&lt;/font&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;
  
  &lt;font color="#990000"&gt;...&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;end&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;
&lt;p&gt;Does your language have a Toolbox? Perhaps it is time to create one, or to switch to another language?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-4085668590060450928?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/4085668590060450928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=4085668590060450928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4085668590060450928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4085668590060450928'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/08/ruby-toolbox.html' title='The Ruby Toolbox'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-3905987319732132048</id><published>2010-08-16T07:50:00.000+02:00</published><updated>2010-08-16T07:50:32.314+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Good Practices for Rich Web Applications</title><content type='html'>&lt;h2&gt;Use jQuery&lt;/h2&gt;

&lt;p&gt;jQuery is the best thing that has happened to Javascript since it got first class functions in version 1.2. The library is elegant, powerful and has exactly the right level of abstraction for working with the DOM. There is nothing more to say. Learn it and use it. Good resources are: &lt;a href="http://api.jquery.com/l"&gt;the jQuery API&lt;/a&gt;, &lt;a href="http://dl.dropbox.com/u/7283184/jquery-api-1.4.2.html"&gt;my view of the jQuery API&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Learn Javascript&lt;/h2&gt;

&lt;p&gt;Javascript is the &lt;a href="http://oredev.org/2010/sessions/javascript-the-language-of-the-web"&gt;programming language of the web&lt;/a&gt;. Learn it! Javascript is different from most other programming languages. It is dynamic, it has prototypical inheritance, and works more like Scheme than any of the languages that you are probably used to. If you want to learn Javascript you should get the following books, &lt;a href="http://www.amazon.com/gp/product/0262560992?tag=thtasta-20"&gt;The Little Schemer&lt;/a&gt;, &lt;a href="http://www.amazon.com/gp/product/026256100X?tag=thtasta-20"&gt;The Seasoned Schemer&lt;/a&gt;, &lt;a href="http://www.amazon.com/gp/product/0596517742?tag=thtasta-20"&gt;Javascript, the Good Parts&lt;/a&gt;, and possibly &lt;a href="http://www.amazon.com/Performance-JavaScript-Faster-Application-Interfaces/dp/059680279X?tag=thtasta-20"&gt;High Performance Javascript&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Learn CSS&lt;/h2&gt;

&lt;p&gt;Many programmers think that CSS is the language of designers and not programmers. This is not the case at all. If you are lucky enough to have a designer on your team (most people don't), CSS is the language with which you communicate. It is the interface between designers and programmers and as a programmer you should know it better than the designers. By knowing CSS well you will reduce the misunderstandings between you and your designer.&lt;/p&gt;

&lt;p&gt;Unfortunately, many designers don't care about how code looks, as long as the design looks good on the surface. It will be up to you to make sure that the CSS doesn't get out out of hand. It will also be up to you to keep the HTML clean, and a good way to do this is to use semantic HTML, combined with CSS. You have no idea what the designers can come up with.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;&amp;lt;!-- &lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;  Old School rounded corners, invented by a GOOD designer. &lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;  All this code was actually needed to achieve the purpose.&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;  --&amp;gt;&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;style&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;font color="#993399"&gt;.t&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#0000FF"&gt;background:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;url&lt;/font&gt;&lt;/i&gt;(&lt;i&gt;&lt;font color="#009900"&gt;dot.gif&lt;/font&gt;&lt;/i&gt;) &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;repeat-x&lt;/font&gt;&lt;/i&gt;; &lt;font color="#0000FF"&gt;width:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;20em&lt;/font&gt;&lt;/i&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#993399"&gt;.b&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#0000FF"&gt;background:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;url&lt;/font&gt;&lt;/i&gt;(&lt;i&gt;&lt;font color="#009900"&gt;dot.gif&lt;/font&gt;&lt;/i&gt;) &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;100%&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;repeat-x&lt;/font&gt;&lt;/i&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#993399"&gt;.l&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#0000FF"&gt;background:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;url&lt;/font&gt;&lt;/i&gt;(&lt;i&gt;&lt;font color="#009900"&gt;dot.gif&lt;/font&gt;&lt;/i&gt;) &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;repeat-y&lt;/font&gt;&lt;/i&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#993399"&gt;.r&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#0000FF"&gt;background:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;url&lt;/font&gt;&lt;/i&gt;(&lt;i&gt;&lt;font color="#009900"&gt;dot.gif&lt;/font&gt;&lt;/i&gt;) &lt;i&gt;&lt;font color="#009900"&gt;100%&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;repeat-y&lt;/font&gt;&lt;/i&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#993399"&gt;.bl&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#0000FF"&gt;background:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;url&lt;/font&gt;&lt;/i&gt;(&lt;i&gt;&lt;font color="#009900"&gt;bl.gif&lt;/font&gt;&lt;/i&gt;) &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;100%&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;no-repeat&lt;/font&gt;&lt;/i&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#993399"&gt;.br&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#0000FF"&gt;background:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;url&lt;/font&gt;&lt;/i&gt;(&lt;i&gt;&lt;font color="#009900"&gt;br.gif&lt;/font&gt;&lt;/i&gt;) &lt;i&gt;&lt;font color="#009900"&gt;100%&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;100%&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;no-repeat&lt;/font&gt;&lt;/i&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#993399"&gt;.tl&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#0000FF"&gt;background:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;url&lt;/font&gt;&lt;/i&gt;(&lt;i&gt;&lt;font color="#009900"&gt;tl.gif&lt;/font&gt;&lt;/i&gt;) &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;no-repeat&lt;/font&gt;&lt;/i&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#993399"&gt;.tr&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#0000FF"&gt;background:&lt;/font&gt; &lt;i&gt;&lt;font color="#009900"&gt;url&lt;/font&gt;&lt;/i&gt;(&lt;i&gt;&lt;font color="#009900"&gt;tr.gif&lt;/font&gt;&lt;/i&gt;) &lt;i&gt;&lt;font color="#009900"&gt;100%&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;0&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="#009900"&gt;no-repeat&lt;/font&gt;&lt;/i&gt;; &lt;font color="#0000FF"&gt;padding:&lt;/font&gt;&lt;i&gt;&lt;font color="#009900"&gt;10px&lt;/font&gt;&lt;/i&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/style&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"t"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"b"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"l"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
      &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"r"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
        &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"bl"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
          &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"br"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
            &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"tl"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
              &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"tr"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
                Lorem ipsum dolor sit amet consectetur adipisicing elit
              &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
            &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
          &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
        &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
      &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;As an additional benefit you will become better at jQuery. Not only is CSS the query language of the browsers it is the query language of jQuery. Jariba!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.amazon.com/Bulletproof-Web-Design-flexibility-protecting/dp/0321509021?tag=thtasta-20"&gt;Bulletproof Web Design&lt;/a&gt; is a good book web design, including CSS.&lt;/p&gt;

&lt;h2&gt;Decide how "Rich" your application should be&lt;/h2&gt;

&lt;p&gt;How rich should your application be? The scale varies from no Javascript to only Javascript, but you will probably want to land somewhere in between. Here are a few suggestions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No Javascript, everything is server generated.&lt;/li&gt;
&lt;li&gt;Slightly enhanced pages, simple validations, but no Ajax.&lt;/li&gt;
&lt;li&gt;Ajax enhanced pages, but every page still reloads frequently.&lt;/li&gt;
&lt;li&gt;Single page per area, entire area is handled by Javascript.&lt;/li&gt;
&lt;li&gt;Only Javascript, Ajax interaction with the server&lt;/li&gt;
&lt;li&gt;Only Javascript, no interaction with the server.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The important thing is to &lt;em&gt;make a decision&lt;/em&gt;. If you don't make the decision, everyone will do different things on different parts of the application and you will loose consistency. In GUI, consistency is king. Make a decision and move on, you can always change your decision later.&lt;/p&gt;

&lt;h2&gt;Organize your code&lt;/h2&gt;

&lt;h3&gt;Javascript&lt;/h3&gt;

&lt;p&gt;Make sure that all your Javascript code is namespaced properly. It is impolite to pollute the global namespace and it will bite you in the end. A simple variable declaration will do.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Common namespace for your entire application&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// This declaration lets you split your code of multiple files.&lt;/font&gt;&lt;/i&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// If MyNamespace is defined use it, otherwise declare it.&lt;/font&gt;&lt;/i&gt;
MyNamespace &lt;font color="#990000"&gt;=&lt;/font&gt; MyNamespace &lt;font color="#990000"&gt;||&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;But, of course, it is also possible to get fancy and encapsulate the functions that you don't want to expose, if that is your cup of tea.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;MyNamespace &lt;font color="#990000"&gt;=&lt;/font&gt; MyNamespace &lt;font color="#990000"&gt;||&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;

MyNamespace&lt;font color="#990000"&gt;.&lt;/font&gt;Tournament &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
 &lt;i&gt;&lt;font color="#9A1900"&gt;// Private stuff&lt;/font&gt;&lt;/i&gt;
 &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; tournamentCount &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
 &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;addTournament&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;tournament&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
  tournamentCount&lt;font color="#990000"&gt;++;&lt;/font&gt;
 &lt;font color="#FF0000"&gt;}&lt;/font&gt;
 
 &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
  &lt;i&gt;&lt;font color="#9A1900"&gt;//public stuff&lt;/font&gt;&lt;/i&gt;
  numberOfTournaments&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
   &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; tournamentCount&lt;font color="#990000"&gt;;&lt;/font&gt;
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;
 &lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;You should also separate your Javascript code into different files. The namespace idiom above helps to have the same namespace across multiple files. The same principles as with other type of code is valid with Javascript, organize the code by area, when it changes, where it is used, etc. Don't be afraid of the additional load time, splitting the files will give you. The files can easily be concatenated with tools  like &lt;a href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt;, &lt;a href="http://www.scons.org/"&gt;SCons&lt;/a&gt;,  &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt; or even a simple:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;$ cat file1&lt;font color="#990000"&gt;.&lt;/font&gt;js file2&lt;font color="#990000"&gt;.&lt;/font&gt;js file3&lt;font color="#990000"&gt;.&lt;/font&gt;js &lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt; all&lt;font color="#990000"&gt;.&lt;/font&gt;js

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;They can also be compressed with &lt;a href="http://www.crockford.com/javascript/jsmin.html"&gt;JSMin&lt;/a&gt; or &lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;YUI Compressor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Optimize your environment for development, not for production!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;HTML&lt;/h3&gt;

&lt;p&gt;HTML is code! Divide your pages into partials by responsibilities. It allows you to keep your pages DRY and readable. &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;The Single Responsibility Principle&lt;/a&gt; applies to HTML too.&lt;/p&gt;

&lt;p&gt;Make sure you keep the Javascript with the code that it manipulates. If you, for example, have a calendar partial that uses &lt;a href="http://jqueryui.com/demos/datepicker/"&gt;jQuery DatePicker&lt;/a&gt;, you have to make sure that the partial includes all the necessary Javascript to configure the calendar. Don't keep Javascript code in the page away from the partial. &lt;a href="http://c2.com/cgi/wiki?CommonClosurePrinciple"&gt;Things that change together should be together&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;CSS&lt;/h3&gt;

&lt;p&gt;Stylesheets are code too. They should also be split into areas that allow you to easily find and navigate them. Use &lt;a href="http://sass-lang.com/"&gt;Sass or SCCS&lt;/a&gt; to keep your CSS files DRY. Sass is good for designers to. It gives them the ability to use variable names, mixins, etc. and simplifies their usage of semantic names such as &lt;em&gt;notice&lt;/em&gt;, and &lt;em&gt;sidebar&lt;/em&gt; instead of &lt;em&gt;yellow&lt;/em&gt; and &lt;em&gt;left&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Optimize your environment for development, not for production!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Separate your Javascript from your HTML&lt;/h2&gt;

&lt;p&gt;All too often I see generated HTML pages with Javascript code in them. Don't do it. Keep the HTML free from Javascript.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;&amp;lt;!-- DON'T DO THIS!  --&amp;gt;&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;button&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;'update-button'&lt;/font&gt; &lt;font color="#009900"&gt;onclick&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"MyNamespace.updateList();"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;Update List&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/button&amp;gt;&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// In the Javascript file for the page.&lt;/font&gt;&lt;/i&gt;
MyNamespace&lt;font color="#990000"&gt;.&lt;/font&gt;updateList &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#990000"&gt;...&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;


&lt;font color="#990000"&gt;&amp;lt;!--&lt;/font&gt; DO THIS&lt;font color="#990000"&gt;!&lt;/font&gt; &lt;font color="#990000"&gt;--&amp;gt;&lt;/font&gt;
&lt;font color="#990000"&gt;&amp;lt;&lt;/font&gt;button id&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;'update-button'&lt;/font&gt;&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt;Update List&lt;font color="#990000"&gt;&amp;lt;/&lt;/font&gt;button&lt;font color="#990000"&gt;&amp;gt;&lt;/font&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// In the Javascript file for the page.&lt;/font&gt;&lt;/i&gt;
MyNamespace&lt;font color="#990000"&gt;.&lt;/font&gt;updateList &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;font color="#990000"&gt;...&lt;/font&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;

$&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
  $&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"#update-button"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;click&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
    MyNamespace&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;updateList&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;It may seem like there is a lot more code in the good example, but notice the symmetry. The code that attaches the listener is in the same file as the code that uses the listener. This is good. Symmetry is good.&lt;/p&gt;

&lt;h3&gt;Use clone()&lt;/h3&gt;

&lt;p&gt;Separating the HTML and the Javascript goes both ways. Don't generate HTML code in Javascript. It doesn't matter that it is super simple to do it using &lt;em&gt;jQuery.html()&lt;/em&gt;. Keep them separate, use &lt;em&gt;jQuery.clone()&lt;/em&gt; instead.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// DON'T DO THIS&lt;/font&gt;&lt;/i&gt;
$&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"&amp;lt;li data-id='123'&amp;gt;My new item&amp;lt;/li&amp;gt;"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;appendTo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"ul"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
&lt;i&gt;&lt;font color="#9A1900"&gt;// OR THIS&lt;/font&gt;&lt;/i&gt;
$&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"ul"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;append&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"&amp;lt;li data-id='123'&amp;gt;My new item&amp;lt;/li&amp;gt;"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;


&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;&amp;lt;!-- DO THIS --&amp;gt;&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;ul&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;li&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"list-template"&lt;/font&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"template"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;All .template are hidden (display: none) in the CSS&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/li&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/ul&amp;gt;&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// AND THIS&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; $clone &lt;font color="#990000"&gt;=&lt;/font&gt; $&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"#list-template"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;clone&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;
$clone&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;attr&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"data-id"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#FF0000"&gt;"123"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;text&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"My new item"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;removeClass&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"template"&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;
$&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;"ul"&lt;/font&gt;&lt;font color="#990000"&gt;).&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;append&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;$clone&lt;font color="#990000"&gt;);&lt;/font&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The point of this is, again, to keep the HTML separate from the Javascript.&lt;/p&gt;

&lt;h2&gt;Decide how content flows between, the page, Javascript and the Server.&lt;/h2&gt;

&lt;p&gt;Once you have decided how rich your application should be, you have to decide on a method for moving the data between the HTML Page, Javascript and the Server. My preferred choice is to have every page that is served from the server include a &lt;em&gt;context object&lt;/em&gt; with all the static data for the page and to have additional data that belongs to parts of the page be sent as &lt;em&gt;data-attributes&lt;/em&gt; on the elements concerned.&lt;/p&gt;

&lt;p&gt;The context object will contain all the data that is commonly needed in the page.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;// Sample context object that is generated with the page.&lt;/font&gt;&lt;/i&gt;
MyNamespace &lt;font color="#990000"&gt;=&lt;/font&gt; MyNamespace &lt;font color="#990000"&gt;||&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
MyNamespace&lt;font color="#990000"&gt;.&lt;/font&gt;Context &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
  user&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
    id&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"28"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
    name&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"Anders Janmyr"&lt;/font&gt;
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
  tournament&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;
    id&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"78344"&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt;
    name&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#FF0000"&gt;"Fifa World Cup"&lt;/font&gt;
  &lt;font color="#FF0000"&gt;}&lt;/font&gt;
&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;I use the context object(s) to keep state on the client to. If it is important that the page looks exactly the same, even if the user reloads the page, I make sure that the state I stick into my context object is synched back to the server. This can easily be done, asynchronously, with Ajax and does not affect performance noticeable.&lt;/p&gt;

&lt;p&gt;Elements specific data is sent along with the element it defines.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;&amp;lt;!-- Element specific data attached to the elements with data-attributes --&amp;gt;&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;ul&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"tournament-menu"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;li&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;data-id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"78344"&lt;/font&gt; &lt;font color="#009900"&gt;data-participant-count&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"64"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;Fifa World Cup&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/li&amp;gt;&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;li&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;data-id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"666"&lt;/font&gt;  &lt;font color="#009900"&gt;data-participant-count&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"44"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;Americas Cup&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/li&amp;gt;&lt;/font&gt;&lt;/b&gt;
  &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;li&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;data-id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"1464"&lt;/font&gt; &lt;font color="#009900"&gt;data-participant-count&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"32"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;Rugby World Cup&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/li&amp;gt;&lt;/font&gt;&lt;/b&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/ul&amp;gt;&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The same argument as with the context object applies, as soon as I change an element in the GUI i need to feed that information back to the server. With elements I usually send the information to the server before updating the GUI, since element specific data is usually permanent data and not just session data.&lt;/p&gt;

&lt;p&gt;An alternative solution to the &lt;em&gt;context object&lt;/em&gt; above is to use the body element as the data-container, like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;body&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;data-user-id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"28"&lt;/font&gt; &lt;font color="#009900"&gt;data-user-name&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"Anders Janmyr"&lt;/font&gt; &lt;font color="#009900"&gt;data-tournament-id&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"78344"&lt;/font&gt; &lt;font color="#009900"&gt;data-tournament-name&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"Fifa World Cup"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;I tend to use the context object because I find it easier to add functionality to it than to the DOM element.&lt;/p&gt;

&lt;p&gt;Only send the data that is needed to the client with the page. The rest of the data should be loaded on demand, with Ajax. Both JSON data and HTML templates can be loaded on demand. There is no need to deliver the entire page at once. Experiment and do what gives the best user experience.&lt;/p&gt;

&lt;h2&gt;Use file watchers to speed up feedback&lt;/h2&gt;

&lt;p&gt;If you compare the feedback cycle of Javascript and HTML development to Java and C# development, you are probably very happy with the short, tight feedback loop. This doesn't mean that you should be content. A feedback cycle cannot be too short.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://xrefresh.binaryage.com/"&gt;xrefresh&lt;/a&gt; for Firefox and IE, and &lt;a href="http://github.com/mockko/livereload"&gt;LiveReload&lt;/a&gt; for Safari and Chrome, are a couple of tools that will tighten your feedback loop even more.&lt;/p&gt;

&lt;p&gt;Both tools are file watchers that listen to changes for files and refresh the browser when they change. If you combine this with two screens, you will have one screen for the browser, that updates continuously, while you edit your code on the other screen. Fabulous!&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Rich web applications are very close to the traditional client-server model. We have to keep state on the client side to give the user a good experience. At the same time the application state, and indeed the entire application, can be swept away by a click of a button or a page reload.&lt;/p&gt;

&lt;p&gt;This puts new demands on us as developers. We have to realize that we are responsible for the entire application, not just the business logic, but the HTML and CSS too. More that anything, we have to realize that Javascript is a first class programming language with its own programming techniques, which we need to master to be able to develop good web applications.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-3905987319732132048?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/3905987319732132048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=3905987319732132048' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/3905987319732132048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/3905987319732132048'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/08/good-practices-for-rich-web.html' title='Good Practices for Rich Web Applications'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-8444206403993669760</id><published>2010-08-12T07:12:00.000+02:00</published><updated>2010-08-12T07:12:33.421+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='methods'/><title type='text'>No Deadlines</title><content type='html'>&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;deadline&lt;/strong&gt;, from New Oxford American Dictionary&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;the latest time or date by which something should be completed : the deadline for submissions is February 5th.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;historical a line drawn around a prison beyond which prisoners were liable to be shot.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Deadlines in software development induce unnecessary stress, and transform otherwise enjoyable activities into chores.&lt;/p&gt;

&lt;p&gt;We need to replace deadlines with livelines. A liveline is a deployed, working version of a product. It is after the fact, a milestone set when you are done.&lt;/p&gt;

&lt;h2&gt;How Deadlines Are Set&lt;/h2&gt;

&lt;p&gt;Deadlines are set in different ways in different projects.&lt;/p&gt;

&lt;p&gt;In the classic &lt;a href="http://www.amazon.com/Death-March-2nd-Edward-Yourdon/dp/013143635X?tag=thtasta-20"&gt;Death March &lt;/a&gt; project, a deadline is set by someone outside the project with no clue whatsoever about how long it will take. Typically this kind of deadline is based on some external event, where the project will be demonstrated. The event may be a conference, or something similar.&lt;/p&gt;

&lt;p&gt;In Scrum, the deadlines are set by the process itself. Most Scrum projects I have worked with use a two week deadline instead of the recommended 30 days. The team decides how many stories they can complete by that deadline, based on rough estimations done in the sprint planning.&lt;/p&gt;

&lt;p&gt;Some projects set deadlines by a developer being asked (or asking himself) when the task will be done. The developer will say: "I'll have it done by 3 o'clock", a wild guess.&lt;/p&gt;

&lt;p&gt;The problem with all these approaches is that the deadlines are, &lt;em&gt;at best&lt;/em&gt;, based on guesses of the team doing the development. But guesses are guesses, not something you can set a deadline by.&lt;/p&gt;

&lt;p&gt;And deadlines work both ways, a task is &lt;em&gt;very&lt;/em&gt; rarely completed before it's deadline.&lt;/p&gt;

&lt;h2&gt;Kinds of Deadlines&lt;/h2&gt;

&lt;h3&gt;Real Deadlines&lt;/h3&gt;

&lt;p&gt;If a task is not completed by a certain time someone will die. This kind of task is really common in novels and movies. A clock is ticking and if the task is not completed by the time the clock reaches zero, BOOM!&lt;/p&gt;

&lt;p&gt;If have never seen this kind of deadline in software development, but they may exist.&lt;/p&gt;

&lt;h3&gt;Planning Deadlines&lt;/h3&gt;

&lt;p&gt;Some deadlines are set in order to simplify planning. In the large Death March projects, the plan is to show the project at a certain date. In integration projects, the deadlines are set to be able to synchronize with other teams working on the same product.&lt;/p&gt;

&lt;p&gt;This kind of deadlines are actually understandable, but I am arguing that they actually slow down projects by introducing stress, which introduces bugs. The bugs introduce bugs in the dependent projects, and slows down many projects instead of just one.&lt;/p&gt;

&lt;h3&gt;Motivational Deadlines&lt;/h3&gt;

&lt;p&gt;Motivation deadlines are set to get people to work. The assumption is that if a deadline is not set people will procrastinate over different ideas, or just slack off since there is no date set for the release anyway.&lt;/p&gt;

&lt;p&gt;This is, absolutely, the worst kind of deadline. If the team is not motivated enough to do a good job without a deadline, you need to get a new team, not set a deadline.&lt;/p&gt;

&lt;h2&gt;Why Deadlines Are Bad&lt;/h2&gt;

&lt;h3&gt;Stress&lt;/h3&gt;

&lt;p&gt;Consider walking on a one foot wide plank. If it is on the ground it is easy. If it is two meters up it is difficult, but if you put it at twenty meters it is a whole different ballgame. That is what its like with deadlines, they put an unnecessary pressure on people.&lt;/p&gt;

&lt;h3&gt;Loss of Motivation&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;Work&lt;/em&gt; consist of whatever a body is obliged to do, and &lt;em&gt;play&lt;/em&gt; consists of whatever one is not obliged to do. -- Mark Twain&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;In his book, &lt;a href="http://www.amazon.com/Drive-Surprising-Truth-About-Motivates/dp/1594488843?tag=thtasta-20"&gt;Drive&lt;/a&gt;, Dan Pink differentiates between &lt;em&gt;intrinsic&lt;/em&gt; motivation and &lt;em&gt;extrinsic&lt;/em&gt; motivation.&lt;/p&gt;

&lt;p&gt;Extrinsic motivation is motivation driven by carrots and sticks, rewards and punishment. It works well for simple, well-defined tasks.&lt;/p&gt;

&lt;p&gt;Intrinsic motivation works well for creative, ill-defined tasks, like programming.&lt;/p&gt;

&lt;p&gt;Intrinsic motivation is fragile, &lt;em&gt;it disappears in the presence of carrots and sticks&lt;/em&gt;. A deadline is a stick, whether set by ourselves or someone else.&lt;/p&gt;

&lt;h2&gt;Livelines&lt;/h2&gt;

&lt;p&gt;A liveline is, quite simply, a task that is done. When a task is done, it is easy for others to use it, in their plans or in reality. If we want to build a stable house, we should build it on stable ground.&lt;/p&gt;

&lt;p&gt;When using livelines the iteration length is the same length as a task. This is usually a lot shorter than the usual one to four weeks common in Scrum and other agile methods. It also leads to variations in the iteration length.&lt;/p&gt;

&lt;p&gt;If you implement your task all the way into production, you get &lt;a href="http://timothyfitz.wordpress.com/2009/02/10/continuous-deployment-at-imvu-doing-the-impossible-fifty-times-a-day/"&gt;Continuous Deployment&lt;/a&gt; or &lt;a href="http://www.amazon.com/gp/product/0321601912?tag=thtasta-20"&gt;Continuous Delivery&lt;/a&gt;. This puts a lot of pressure on your tooling and on automation but, I believe this is the way to go.&lt;/p&gt;

&lt;p&gt;It is 2010, it is time to get rid of deadlines.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-8444206403993669760?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/8444206403993669760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=8444206403993669760' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/8444206403993669760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/8444206403993669760'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/08/no-deadlines.html' title='No Deadlines'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-2927141579435814930</id><published>2010-06-20T08:22:00.000+02:00</published><updated>2010-06-20T08:22:53.265+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Ruby and Rails Summer Reading</title><content type='html'>&lt;p&gt;If you ask a Ruby programmer why he is using Ruby, you will probably get several answers like: It is dynamic. I allows me too keep my code DRY. I get results faster. Aside from all these statements, there is one statement that almost always comes up.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;I use Ruby because it makes me happy!&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="http://3.bp.blogspot.com/_ELioussa2vo/TB2yZpIl5XI/AAAAAAAAAfw/vCZCP2XcwZE/s320/smiley.jpg" /&gt;&lt;/div&gt;


&lt;p&gt;If you search Amazon for Ruby you get 8,829 Results and if you search for Rails you get
14,113 Results. What books should you get?&lt;/p&gt;

&lt;p&gt;Here are the books I recommend:&lt;/p&gt;

&lt;h2&gt;Ruby&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.amazon.com/Beginning-Ruby-Novice-Professional/dp/1590597664?tag=thtasta-20"&gt;Beginning Ruby&lt;/a&gt; is a superb book for people coming new to Ruby.&lt;/p&gt;

&lt;p&gt;If you are not a complete novice, you should instead go for
&lt;a href="http://www.amazon.com/Well-Grounded-Rubyist-David-Black/dp/1933988657?tag=thtasta-20"&gt;The Well Grounded Rybyist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When you have finished &lt;em&gt;the Well Grounded Rubyist&lt;/em&gt;, you are ready for &lt;a href="http://www.amazon.com/Metaprogramming-Ruby-Facets-Paolo-Perrotta/dp/1934356476/?tag=thtasta-20"&gt;Metaprogramming Ruby&lt;/a&gt; where you learn metaprogramming techniques to help you keep your code DRY and readable.&lt;/p&gt;

&lt;h2&gt;Rails&lt;/h2&gt;

&lt;p&gt;Since Rails is currently being updated to version 3, there are not that many books available. I can recommend &lt;a href="http://www.amazon.com/Rails-Way-Addison-Wesley-Professional-Ruby/dp/0321601661?tag=thtasta-20"&gt;The Rails3 Way&lt;/a&gt;, currently only &lt;a href="http://www.informit.com/store/product.aspx?isbn=0132480336"&gt;available as a Rough-Cut&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The lack of updated books is not a problem. The &lt;a href="http://guides.rails.info/getting_started.html"&gt;The Ruby on Rails Guides&lt;/a&gt; are excellent. Make sure you select the edge version.&lt;/p&gt;

&lt;p&gt;Even more information is available through the videos from &lt;a href="http://en.oreilly.com/rails2010"&gt;Railsconf&lt;/a&gt;, &lt;a href="http://railsconf.blip.tv/rss/itunes/"&gt;subscribe to them in iTunes&lt;/a&gt;. The first videos where published, the day after they were filmed. Fantastic!&lt;/p&gt;

&lt;p&gt;Have a happy Ruby-red summer.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-2927141579435814930?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/2927141579435814930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=2927141579435814930' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2927141579435814930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/2927141579435814930'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/06/ruby-and-rails-summer-reading.html' title='Ruby and Rails Summer Reading'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ELioussa2vo/TB2yZpIl5XI/AAAAAAAAAfw/vCZCP2XcwZE/s72-c/smiley.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-4742619725553739254</id><published>2010-06-08T21:34:00.000+02:00</published><updated>2010-06-08T21:34:14.013+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Seamless Web Development</title><content type='html'>&lt;p&gt;Do you remember the time before 9/11 when you could arrive to the airport 10 minutes before the plane's departure and just walk on to the plane. Now, you have to arrive at least an hour before the plane departs and you have to strip to get through a security.&lt;/p&gt;

&lt;p&gt;The security is just for show. I don't know how many times I have forgotten a bottle in my carry-on and I haven't noticed it until I unpacked the bag at home. There a number of ways to get a big bang for your bucks, that aren't checked at security&lt;/p&gt;

&lt;p&gt;&lt;img src="http://imgs.xkcd.com/comics/bag_check.png" title="XKCD Bag Check" alt="XKCD Bag Check" /&gt;&lt;/p&gt;

&lt;p&gt;So what does this have to do with web development? Web development in a compiled language is like traveling after the terrorist attacks. You have to go through a lot of time consuming controls that are, mostly, for show. This dramatically slows down your development speed.&lt;/p&gt;

&lt;p&gt;Since I did my &lt;a href="http://anders.janmyr.com/2010/04/aspnet-mvc-vs-rails3.html"&gt;comparison between Rails and .NET MVC&lt;/a&gt; I have done a lot of coding in both environments, and my conclusion is that Rails is a lot faster to develop with than .NET MVC.&lt;/p&gt;

&lt;p&gt;The reason for this is that .NET MVC puts up a lot of seams that hinders development.&lt;/p&gt;

&lt;h2&gt;Seam #1, Runtime Development&lt;/h2&gt;

&lt;p&gt;When I'm using Rails for development I very rarely restart the server. When I make a change to the view, controller, model or database,  the changes are visible on the next request. Immediate feedback!&lt;/p&gt;

&lt;p&gt;In Visual Studio, there is something called "Edit and Continue", that you can set to allow you to make changes to the code while you are debugging. Mooah ha ha ha ha ha ha ha haaaaaaa! This sucks so bad that I cannot help bursting out in a crazy laughter. The flow disappears.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://2.bp.blogspot.com/_ELioussa2vo/TA5505v-TUI/AAAAAAAAAfg/fo658aXs84U/s320/Edit_and_continue.png" title="Edit and Continue in your face!" alt="Edit and Continue" /&gt;&lt;/p&gt;

&lt;p&gt;If I make changes &lt;em&gt;to the view&lt;/em&gt; I can continue, unless I make changes to the I18N resources, because these are obviously not mutable. WTF!&lt;/p&gt;

&lt;p&gt;Sometimes it is actually possible to make changes to the code, but when you try to save the changes "Edit and Continue"'s big brother appears and smacks you in the head, and the flow is gone again!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://1.bp.blogspot.com/_ELioussa2vo/TA555qfu4AI/AAAAAAAAAfo/dfsQxw_s-H8/s1600/Edit_and_continue2.png" title="Mooah ha ha ha ha ha haaaaaaa!" alt="Edit and Continue2" /&gt;&lt;/p&gt;

&lt;p&gt;There is really no &lt;em&gt;good&lt;/em&gt; reason for this. I'm sure there are a number of technical reasons having to do with type safety and class reloading, but I don't care. Just reload everything, do it fast and unnoticeable!&lt;/p&gt;

&lt;h2&gt;Seam #2, The Javascript Impedance Mismatch&lt;/h2&gt;

&lt;p&gt;Hopefully everyone has realized that Javascript is the hottest thing in web development! A language that has been spat on, and laughed at, has become the most wide spread programming language in the world. It's available in every browser and on every programming platform.&lt;/p&gt;

&lt;p&gt;I have been talking about the greatness of Javascript for a few years now and it is great to see when someone finally get it.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;"Its great, I just change this little thing, then click reload, and it works immediately!" -- A collegue, seeing the coolness of Javascript.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Javascript is Lisp in C-clothing and Lisp is the language that God used to create the world.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://imgs.xkcd.com/comics/lisp.jpg" title="XKCD Lisp" alt="Lisp" /&gt;&lt;/p&gt;

&lt;p&gt;OK, Javascript is cool, and we all use it, but what is this impedance mumbo jumbo? Since a large part of a modern web application will be developed in Javascript, when we move over to the server side and everything is static and compiled, we are in for a lot of frustration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Development Flow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make a change to the GUI, in Javascript.&lt;/li&gt;
&lt;li&gt;Reload&lt;/li&gt;
&lt;li&gt;Make another change&lt;/li&gt;
&lt;li&gt;Reload&lt;/li&gt;
&lt;li&gt;Realizing that you need to change the controller for the next change.&lt;/li&gt;
&lt;li&gt;Aaaaaaaaaarrrrrrrrrrrggggghhhhhhhh, I have to restart the application.&lt;/li&gt;
&lt;li&gt;What was it that I was working on again? I'll go for a cup of coffee!&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This is the Javascript impedance mismatch. If you are developing in a dynamic language you expect it to work like this all the time. You get used to it. It is better!&lt;/p&gt;

&lt;p&gt;With Rails and Ruby, you get the same flow on the backend as you do on the client. The static-dynamic mismatch is gone. (There is still a language mismatch, between Javascript and Ruby, but it is minuscule by comparison.)&lt;/p&gt;

&lt;h2&gt;Seam #3, Cruft&lt;/h2&gt;

&lt;p&gt;Compare the following two partials&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;&amp;lt;!-- BookedCustomer.aspx partial in .NET MVC--&amp;gt;&lt;/font&gt;&lt;/i&gt;
&amp;lt;%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;Bergqvists.Models.Booking&amp;gt;&lt;/font&gt;&lt;/b&gt;" %&amp;gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"view"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"customer title"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;&amp;lt;%= Html.ActionLink(Model.Customer.Fullname, "Details", "Customers", new { Id = Model.CustomerID}, null) %&amp;gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"status"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;&amp;lt;%= Html.Encode(Model.BookingStatus.Name) %&amp;gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"booking-date"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;&amp;lt;%=ViewRes.BookingStrings.BookedOn %&amp;gt;
    &amp;lt;%= string.Format("{0:D}", Model.BookingDate) %&amp;gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
&amp;lt;% Html.RenderPartial("BookingStatusLinks", Model);%&amp;gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;&amp;lt;!-- _booked_customer.html.erb partial --&amp;gt;&lt;/font&gt;&lt;/i&gt;
&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"view"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"customer title"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;&amp;lt;%= link_to customer.fullname, customer_path(customer)&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"status"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;&amp;lt;%= customer.booking_status.name %&amp;gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;
    &lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;div&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;class&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt;&lt;font color="#FF0000"&gt;"booking-date"&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;gt;&lt;/font&gt;&lt;/b&gt;&amp;lt;%=t :booked_on %&amp;gt;
    &amp;lt;%= customer.booking_date, :format =&amp;gt; :short %&amp;gt; %&amp;gt;&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;

&lt;b&gt;&lt;font color="#0000FF"&gt;&amp;lt;/div&amp;gt;&lt;/font&gt;&lt;/b&gt;
&amp;lt;%= render :booking_status_links, :locals =&amp;gt; {:customer =&amp;gt; customer} %&amp;gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;As you can see the corresponding ERB is not much different, but at least everything in the code is meaningful. And what customer value does the first line bring?&lt;/p&gt;

&lt;p&gt;  &amp;lt;%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl&amp;lt;Bergqvists.Models.Booking&gt;" %&gt;&lt;/p&gt;

&lt;p&gt;Nada! Zilch! It is only there to please the compiler. Cruft!&lt;/p&gt;

&lt;p&gt;Now, most Ruby programmers I know use HAML instead of ERB and this cleans the view up considerably.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;tt&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;view
  &lt;font color="#990000"&gt;.&lt;/font&gt;customer&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#009900"&gt;title&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt; link_to customer&lt;font color="#990000"&gt;.&lt;/font&gt;fullname&lt;font color="#990000"&gt;,&lt;/font&gt; customer_path&lt;font color="#990000"&gt;(&lt;/font&gt;customer&lt;font color="#990000"&gt;)&lt;/font&gt;
  &lt;font color="#990000"&gt;.&lt;/font&gt;&lt;font color="#009900"&gt;status&lt;/font&gt;&lt;font color="#990000"&gt;=&lt;/font&gt; customer&lt;font color="#990000"&gt;.&lt;/font&gt;booking_status&lt;font color="#990000"&gt;.&lt;/font&gt;name
  &lt;font color="#990000"&gt;.&lt;/font&gt;booking-date
    &lt;font color="#990000"&gt;=&lt;/font&gt; t &lt;font color="#990000"&gt;:&lt;/font&gt;booked_on
    &lt;font color="#990000"&gt;=&lt;/font&gt; customer&lt;font color="#990000"&gt;.&lt;/font&gt;booking_date&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;format &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;short

&lt;font color="#990000"&gt;=&lt;/font&gt; render &lt;font color="#990000"&gt;:&lt;/font&gt;booking_status_links&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt;locals &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; {&lt;font color="#990000"&gt;:&lt;/font&gt;customer &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; customer}

&lt;/tt&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Beautiful!&lt;/p&gt;

&lt;p&gt;Comparing Haml with ASP is not really fair, since it is possible to use &lt;a href="todo"&gt;NHaml&lt;/a&gt; instead of ASP in .NET MVC, but no one I know does that, maybe I hang with the wrong .Net people. NHAML is great, please switch it to the default for .NET MVC.&lt;/p&gt;

&lt;p&gt;The example above is in the view layer. But the cruft spreads all over the stack.&lt;/p&gt;

&lt;h2&gt;Seam #4, Testing&lt;/h2&gt;

&lt;p&gt;Testing is always an interesting topic. The number one reason testing is not done is that it is to cumbersome. In .NET MVC I find it painful to test the controller and view layers, to the extent that I don't do it. With Rails on the other hand, you are setup for test from the start.&lt;/p&gt;

&lt;p&gt;I always try to put as much code as possible into the model layer, but some code belongs in the controller. I want it to be easily tested too.&lt;/p&gt;

&lt;p&gt;It is also worth noting that the Ruby community is driving the testing profession forward, with tools like RSpec, Capybara, Webkit and Cucumber.&lt;/p&gt;

&lt;p&gt;Yes, I know that there are several implementation languages for Cucumber. It's possible to write your steps, in C# or Java or almost any other language. My advice is, &lt;em&gt;don't do it!&lt;/em&gt; There is compilation, waiting, pain and suffering down that road. Use a dynamic language to test your code.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;So what's my point? It's time to stop compiling and quit slacking off.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://imgs.xkcd.com/comics/compiling.png" title="XKCD Compiling" alt="XKCD Compiling" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rails should be the default choice for web development.&lt;/strong&gt; You should have a very good reason for not choosing Rails on your next web project.&lt;/p&gt;

&lt;p&gt;I know it may feel tough to have invested many years in something else, but as the turks say.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;No matter how far down the wrong path you've gone, turn back! --- Turkish Proverb&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Don't take my word for it. Check out &lt;a href="http://www.infoq.com/articles/architecting-tekpub"&gt;this interview&lt;/a&gt; and &lt;a href="http://www.infoq.com/presentations/ford-large-rails"&gt;this presentation&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-4742619725553739254?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/4742619725553739254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=4742619725553739254' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4742619725553739254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4742619725553739254'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/06/seamless-web-development.html' title='Seamless Web Development'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ELioussa2vo/TA5505v-TUI/AAAAAAAAAfg/fo658aXs84U/s72-c/Edit_and_continue.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-4427847100578187852</id><published>2010-05-20T15:51:00.000+02:00</published><updated>2010-05-20T15:51:21.908+02:00</updated><title type='text'>&gt;Making Windows Keyboard Feel like OS X</title><content type='html'>&lt;p&gt;I have been unfortunate enough to have to start working with Windows on my Mac. I am using Bootcamp and VMWare Fusion. If I only need to make minor changes I can boot the Bootcamp partition via VMWare so I don&amp;#8217;t have to reboot the computer every time I have to use Windows. VMWare allows me to customize my mappings to send the keys that I am used to using, so if this was the only way I was using Windows, that would be quite alright. &lt;/p&gt;

&lt;p&gt;Since I need to develop in Visual Studio, using VMWare is only an option for very small projects, or the whole experience will become painfully slow.&lt;/p&gt;

&lt;p&gt;Bootcamp does not support remapping the keys. Agony! Well, I found a solution.&lt;/p&gt;

&lt;h3 id="remapping_keys"&gt;Remapping Keys&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;I am using a US keyboard layout&lt;/em&gt;, your key mappings may be different.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.randyrants.com/2008/12/sharpkeys_30.html"&gt;SharpKeys&lt;/a&gt; is a tool that helps you perform some registry hacks, to allow me to remap the keys that I want to change.&lt;/p&gt;

&lt;p&gt;I use it to remap the Alt and Windows keys, since they are reversed on the Mac. I also move the &amp;#8220;`~&amp;#8221; down to the bottom left corner where &amp;#8220;|&amp;#34; usually are on Windows. &amp;#8220;|&amp;#34;  are in two different places on a US layout, I don&amp;#8217;t know why.&lt;/p&gt;

&lt;p&gt;Now that I have finished remapping the keys, I am done using SharpKeys. Now all I have to do is to get the Windows key to behave the way they do on the Mac on not like Windows keys.&lt;/p&gt;

&lt;h3 id="setting_up_the_shortcuts"&gt;Setting up the Shortcuts&lt;/h3&gt;

&lt;p&gt;The first thing to do is to disable the normal WindowKey functions. &lt;a href="http://www.sevenforums.com/tutorials/5937-windows-key-shortcuts-enable-disable.html"&gt;Here is a guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.autohotkey.com/"&gt;AutoHotKey&lt;/a&gt; is a tool the lets you remap the functions that are sent when a key is pressed. It can do a whole lot of other cool stuff too, so I encourage you to check it out even if you are not using a Mac. It is a great automation tool.&lt;/p&gt;

&lt;p&gt;Here is my &lt;em&gt;shortcuts.ahk&lt;/em&gt; file. I remap all my CMD-actions to the WinKey, and I also remap the Win- Left, Right, Up and Down to the corresponding Mac shortcuts. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#SingleInstance force
#a::Send ^a
#b::Send ^b
#c::Send ^c
#f::Send ^f
#n::Send ^n
#o::Send ^o
#p::Send ^p
#q::Send !{f4}
#r::Send ^r
#s::Send ^s
#t::Send ^t
#v::Send ^v
#w::Send ^{f4}
#x::Send ^x
#y::Send ^y
#z::Send ^z

#Left::Send {Home}
#Right::Send {End}
#Up::Send {PgUp}
#Down::Send {PgDn}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After this is done it is OK, almost, to start working. The sad part is that this configuration only works with an external keyboard. I couldn&amp;#8217;t get the internal keys mapped properly on my Macbook Pro. But at least it is working.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34049130-4427847100578187852?l=anders.janmyr.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anders.janmyr.com/feeds/4427847100578187852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34049130&amp;postID=4427847100578187852' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4427847100578187852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34049130/posts/default/4427847100578187852'/><link rel='alternate' type='text/html' href='http://anders.janmyr.com/2010/05/making-windows-keyboard-feel-like-os-x.html' title='&gt;Making Windows Keyboard Feel like OS X'/><author><name>Anders Janmyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34049130.post-8537463569716876882</id><published>2010-04-23T10:54:00.001+02:00</published><updated>2010-04-23T12:13:51.188+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='linq'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>ASP.NET MVC vs. Rails3</title><content type='html'>I recently was contacted to implement an ASP.NET MVC application and I saw this as a great opportunity to compare it with Rails3.&lt;br /&gt;
What immediately strikes you when you start with ASP.NET MVC is how similar it is to Rails. No one can steal ideas like Microsoft!&lt;br /&gt;
&lt;table&gt;
    &lt;tbody&gt;
&lt;tr&gt;
        &lt;th&gt;Rails
        &lt;/th&gt;&lt;th&gt;ASP.NET MVC
        &lt;/th&gt;&lt;th&gt;Purpose (if not obvious)
    &lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
        &lt;td&gt;/app/models&lt;/td&gt;
        &lt;td&gt;/Models&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;tr&gt;
        &lt;td&gt;/app/controllers&lt;/td&gt;
        &lt;td&gt;/Controllers&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;tr&gt;
        &lt;td&gt;/app/views&lt;/td&gt;
        &lt;td&gt;/Views&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;tr&gt;
        &lt;td&gt;/public/javascript&lt;/td&gt;
        &lt;td&gt;/Scripts&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;tr&gt;
        &lt;td&gt;/public&lt;/td&gt;
        &lt;td&gt;/Content&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;tr&gt;
        &lt;td&gt;/db&lt;/td&gt;
        &lt;td&gt;/App_Data&lt;/td&gt;
        &lt;td&gt;Database data, such as migrations, and models.&lt;/td&gt;
    &lt;/tr&gt;
&lt;tr&gt;
        &lt;td&gt;/test (unit, functional, fixtures, performance)&lt;/td&gt;
        &lt;td&gt;Separate VS projects&lt;/td&gt;
    &lt;/tr&gt;
&lt;tr&gt;
        &lt;td&gt;/config&lt;/td&gt;
        &lt;td&gt;/Global.asax, /Properties, Web.config&lt;/td&gt;
        &lt;td&gt;Configuration&lt;/td&gt;
    &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;



Project Generation&lt;/h3&gt;
Both Rails and ASP.NET MVC relies on code generation to get you started, but the methods they use are different.&lt;br /&gt;
Rails uses the command line, which is natural since the Rails approach is to not rely on anything but a good programming editor and the command line.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;$ rails tapir
      create  &lt;span style="color: #990000;"&gt;.&lt;/span&gt;gitignore
   &lt;span style="color: #990000;"&gt;...&lt;/span&gt;
      create  app/controllers/application_controller&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
      &lt;span style="color: #990000;"&gt;...&lt;/span&gt;
      create  app/views/layouts
      create  config/database&lt;span style="color: #990000;"&gt;.&lt;/span&gt;yml
      create  db/seeds&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
   &lt;span style="color: #990000;"&gt;...&lt;/span&gt;
      create  public/javascripts/application&lt;span style="color: #990000;"&gt;.&lt;/span&gt;js
   &lt;span style="color: #990000;"&gt;...&lt;/span&gt;
      create  test/unit
   &lt;span style="color: #990000;"&gt;...&lt;/span&gt;
&lt;/tt&gt;&lt;/pre&gt;
ASP.NET MVC uses Wizards inside Visual Studio, which is also expected since Microsoft has a long history of IDE-centric application building.
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_ELioussa2vo/S9FeCW86GtI/AAAAAAAAAeg/Fa-g7QGSjkw/s1600/new_asp_mvc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_ELioussa2vo/S9FeCW86GtI/AAAAAAAAAeg/Fa-g7QGSjkw/s320/new_asp_mvc.png" /&gt;&lt;/a&gt;&lt;/div&gt;
Worth noting is that I didn't really want to use VS Unit Test, since I normally prefer NUnit, but after one hour of googling and testing I gave up and went with VS Unit Test anyway.&lt;br /&gt;
&lt;h3&gt;



Environment&lt;/h3&gt;
When Rails is installed it comes pre-configured with three different environment, development, test and production. It is as easy as writing RAILS_ENV=test to switch from the default development environment to the test environment. In this area Rails really shines. There is nothing similar in ASP.NET MVC.&lt;br /&gt;
&lt;h3&gt;



The Model&lt;/h3&gt;
&lt;h4&gt;



Rails Model&lt;/h4&gt;
Rails comes pre-configured with an ActiveRecord model, if you don't write otherwise. If you want to use something else it is very easy. Supported frameworks are among others, Neo4J, MongoDB, and DataMapper.&lt;br /&gt;
To create a model in Rails3 you use a command line generator. The generator generates a model, a migration and tests. And you can, of course, choose what kind of model you wish to generate (-o), as well as what kind of testing framework you want to use (-t). Here I just go with the default:&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;$ rails g model customer name&lt;span style="color: #990000;"&gt;:&lt;/span&gt;string email&lt;span style="color: #990000;"&gt;:&lt;/span&gt;string
      invoke  active_record
      create    db/migrate&lt;span style="color: #990000;"&gt;/&lt;/span&gt;20100419094010_create_customers&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
      create    app/models/customer&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
      invoke    test_unit
      create      test/unit/customer_test&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
      create      test/fixtures/customers&lt;span style="color: #990000;"&gt;.&lt;/span&gt;yml

&lt;/tt&gt;&lt;/pre&gt;
Rails comes preconfigured with Sqlite3, and you don't have to do anything to configure the default database. Moreover, the configuration is set up to use three different databases, one for each environment.&lt;br /&gt;
Rails, performs all database changes through scripts, migrations. This is invaluable when you want to upgrade a database that is in production, or when multiple developers are changing the same database model. The migration scripts allow seamless migrations between the different databases.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# An example of a migration&lt;/span&gt;&lt;/i&gt;
&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; CreateCustomers &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt; ActiveRecord&lt;span style="color: #990000;"&gt;::&lt;/span&gt;Migration

  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Called when migrating up to this version&lt;/span&gt;&lt;/i&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;self&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;up
    create_table &lt;span style="color: #990000;"&gt;:&lt;/span&gt;customers &lt;b&gt;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;|&lt;/span&gt;t&lt;span style="color: #990000;"&gt;|&lt;/span&gt;
      t&lt;span style="color: #990000;"&gt;.&lt;/span&gt;string &lt;span style="color: #990000;"&gt;:&lt;/span&gt;name
      t&lt;span style="color: #990000;"&gt;.&lt;/span&gt;string &lt;span style="color: #990000;"&gt;:&lt;/span&gt;email
      t&lt;span style="color: #990000;"&gt;.&lt;/span&gt;timestamps
    &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
  
  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Called when migrating down from this version&lt;/span&gt;&lt;/i&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;self&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;down
    drop_table &lt;span style="color: #990000;"&gt;:&lt;/span&gt;customers
  &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
&lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;
To move between the different versions of the database we use the &lt;i&gt;rake db:migrate&lt;/i&gt; command.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Migrate to the latest version&lt;/span&gt;&lt;/i&gt;
$ rake db&lt;span style="color: #990000;"&gt;:&lt;/span&gt;migrate 

&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Migrate to a specific version&lt;/span&gt;&lt;/i&gt;
$ rake db&lt;span style="color: #990000;"&gt;:&lt;/span&gt;migrate &lt;span style="color: #009900;"&gt;VERSION&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: #993399;"&gt;20080906120000&lt;/span&gt; 

&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Rollback one version&lt;/span&gt;&lt;/i&gt;
$ rake db&lt;span style="color: #990000;"&gt;:&lt;/span&gt;rollback 

&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Rollback three versions&lt;/span&gt;&lt;/i&gt;
$ rake db&lt;span style="color: #990000;"&gt;:&lt;/span&gt;rollback &lt;span style="color: #009900;"&gt;STEP&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: #993399;"&gt;3&lt;/span&gt;

&lt;/tt&gt;&lt;/pre&gt;
Read more about migrations in the &lt;a href="http://guides.rubyonrails.org/migrations.html"&gt;Migrations Guide&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;



ASP.NET MVC Model&lt;/h4&gt;
ASP.NET MVC is not a full stack framework and it does not come preconfigured with a model. It is possible to choose between many solutions, such as NHibernate, Entity Framework or LINQ-to-SQL. I choose LINQ-to-SQL because I think it is an elegant, lightweight OR-Mapper, that is easy to work with. Too bad, it isn't prioritized by Microsoft.&lt;br /&gt;
Unfortunately, there is nothing like migrations in LINQ-to-SQL. So I use the LINQ-to-SQL design tool to design the classes.
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_ELioussa2vo/S9FezPBTiuI/AAAAAAAAAeo/2-hPL_i1h70/s1600/linq_to_sql_designer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_ELioussa2vo/S9FezPBTiuI/AAAAAAAAAeo/2-hPL_i1h70/s320/linq_to_sql_designer.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
You can then create the database from the model. It is also possible to do it the opposite way, to create the database first and then generate the model, but I prefer this way.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;// Creating a database from a LINQ-to-SQL DataContext&lt;/span&gt;&lt;/i&gt;
public &lt;span style="color: teal;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;CreateDatabase&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;bool&lt;/span&gt; force&lt;span style="color: #990000;"&gt;)&lt;/span&gt;
&lt;span style="color: red;"&gt;{&lt;/span&gt;
    &lt;span style="color: teal;"&gt;var&lt;/span&gt; db &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: teal;"&gt;new&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;TapirDataContext&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;@&lt;span style="color: red;"&gt;"c:&lt;/span&gt;&lt;span style="color: #cc33cc;"&gt;\t&lt;/span&gt;&lt;span style="color: red;"&gt;apirdb.mdf"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;
    &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;db&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;DatabaseExists&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: #990000;"&gt;||&lt;/span&gt; force&lt;span style="color: #990000;"&gt;)&lt;/span&gt;
    &lt;span style="color: red;"&gt;{&lt;/span&gt;
        Console&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;WriteLine&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Deleting old database..."&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;
        db&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;DeleteDatabase&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;
    &lt;span style="color: red;"&gt;}&lt;/span&gt;
    db&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;CreateDatabase&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;
&lt;span style="color: red;"&gt;}&lt;/span&gt;

&lt;/tt&gt;&lt;/pre&gt;
As you understand this is not a viable solution for migrating a production database, but it is good enough (almost) for development and testing, since I can allow myself to recreate the database every time. Once I get a larger database, the time it takes to set it up will force me to go with a better way. The lack of migrations hurts.&lt;br /&gt;
&lt;h4&gt;



Query Language&lt;/h4&gt;
Rails3 uses AREL, Active Record Relations, and LINQ-to-SQL uses LINQ (surprise!). They are both beautiful solutions and remarkably similar. Both solutions create lazy, composable queries, that are not executed until the latest possible time, when a result is needed. In LINQ, you can see Eric Meijer's Haskell shining through like magic, and in AREL, the beauty of Ruby.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# A simple query with AREL&lt;/span&gt;&lt;/i&gt;
User&lt;span style="color: #990000;"&gt;.&lt;/span&gt;where&lt;span style="color: #990000;"&gt;(&lt;/span&gt;users&lt;span style="color: #990000;"&gt;[:&lt;/span&gt;name&lt;span style="color: #990000;"&gt;].&lt;/span&gt;eq&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'Anders'&lt;/span&gt;&lt;span style="color: #990000;"&gt;)).&lt;/span&gt;order&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'users.id DESC'&lt;/span&gt;&lt;span style="color: #990000;"&gt;).&lt;/span&gt;limit&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;20&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;

&lt;/tt&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;// The same with C#&lt;/span&gt;&lt;/i&gt;
&lt;i&gt;&lt;span style="color: #9a1900;"&gt;// Lambda Syntax&lt;/span&gt;&lt;/i&gt;
db&lt;span style="color: #990000;"&gt;.&lt;/span&gt;Users&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;where&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;u &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; u&lt;span style="color: #990000;"&gt;.&lt;/span&gt;Name &lt;span style="color: #990000;"&gt;==&lt;/span&gt; &lt;span style="color: red;"&gt;"Anders"&lt;/span&gt;&lt;span style="color: #990000;"&gt;).&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;orderBy&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;u &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; u&lt;span style="color: #990000;"&gt;.&lt;/span&gt;Id&lt;span style="color: #990000;"&gt;).&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Take&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;20&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;

&lt;i&gt;&lt;span style="color: #9a1900;"&gt;// LINQ Syntax&lt;/span&gt;&lt;/i&gt;
&lt;span style="color: #990000;"&gt;(&lt;/span&gt;from u &lt;span style="color: teal;"&gt;in&lt;/span&gt; db&lt;span style="color: #990000;"&gt;.&lt;/span&gt;Users
&lt;span style="color: teal;"&gt;where&lt;/span&gt; u&lt;span style="color: #990000;"&gt;.&lt;/span&gt;Name &lt;span style="color: #990000;"&gt;==&lt;/span&gt; &lt;span style="color: red;"&gt;"Anders"&lt;/span&gt;
&lt;span style="color: teal;"&gt;orderby&lt;/span&gt; u&lt;span style="color: #990000;"&gt;.&lt;/span&gt;Id descending
&lt;span style="color: teal;"&gt;select&lt;/span&gt; u&lt;span style="color: #990000;"&gt;).&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Take&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;20&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;

&lt;/tt&gt;&lt;/pre&gt;
One thing that you don't get with LINQ-to-SQL is all the methods that are dynamically created, by need, in Rails, such as &lt;i&gt;find_by_name&lt;/i&gt;, &lt;i&gt;find_by_name_and_age&lt;/i&gt;, etc.&lt;br /&gt;
&lt;h3&gt;



The Controller&lt;/h3&gt;
In ASP.NET MVC, it is easy to create a controller, you just right-click on the controllers folder and select &lt;i&gt;Add &amp;gt; Controller&lt;/i&gt;. You then get a dialog where you can type in the name of the controller and, optionally, if you like to create default methods for the standard CRUD scenario, just select the checkbox.
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_ELioussa2vo/S9Fe8OUhFHI/AAAAAAAAAe4/8ftOIxwf2Vg/s1600/generate_controller.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_ELioussa2vo/S9Fe8OUhFHI/AAAAAAAAAe4/8ftOIxwf2Vg/s320/generate_controller.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;
public &lt;span style="color: teal;"&gt;class&lt;/span&gt; CustomersController &lt;span style="color: #990000;"&gt;:&lt;/span&gt; Controller &lt;span style="color: red;"&gt;{&lt;/span&gt;
      &lt;i&gt;&lt;span style="color: #9a1900;"&gt;// GET: /Customers/&lt;/span&gt;&lt;/i&gt;
      public &lt;span style="color: teal;"&gt;ActionResult&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;Index&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;
          &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;View&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;
      &lt;span style="color: red;"&gt;}&lt;/span&gt;

      &lt;i&gt;&lt;span style="color: #9a1900;"&gt;// GET: /Customers/Details/5&lt;/span&gt;&lt;/i&gt;
      public &lt;span style="color: teal;"&gt;ActionResult&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;Details&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;int&lt;/span&gt; id&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;
          &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;View&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;
      &lt;span style="color: red;"&gt;}&lt;/span&gt;

      &lt;i&gt;&lt;span style="color: #9a1900;"&gt;// GET: /Customers/Create&lt;/span&gt;&lt;/i&gt;
      public &lt;span style="color: teal;"&gt;ActionResult&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;Create&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;
          &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;View&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;
      &lt;span style="color: red;"&gt;}&lt;/span&gt;

      &lt;i&gt;&lt;span style="color: #9a1900;"&gt;// POST: /Customers/Create&lt;/span&gt;&lt;/i&gt;
      &lt;span style="color: #990000;"&gt;[&lt;/span&gt;HttpPost&lt;span style="color: #990000;"&gt;]&lt;/span&gt;
      public &lt;span style="color: teal;"&gt;ActionResult&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;Create&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;FormCollection&lt;/span&gt; collection&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;
          try &lt;span style="color: red;"&gt;{&lt;/span&gt;
              &lt;i&gt;&lt;span style="color: #9a1900;"&gt;// TODO: Add insert logic here&lt;/span&gt;&lt;/i&gt;
              &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;RedirectToAction&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Index"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;
          &lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;
              &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;View&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;
          &lt;span style="color: red;"&gt;}&lt;/span&gt;
      &lt;span style="color: red;"&gt;}&lt;/span&gt;
&lt;span style="color: red;"&gt;}&lt;/span&gt;

&lt;/tt&gt;&lt;/pre&gt;
As you can see the code generated is simple and clear. That is the benefit of MVC, simpler models, views, and controllers.&lt;br /&gt;
The automatic generation of code, that will probably be changed later is commonly known as scaffolding.&lt;br /&gt;
&lt;blockquote&gt;
&lt;b&gt;Scaffolding&lt;/b&gt; is a temporary structure used to support people and material in the construction or repair of buildings and other large structures. --Wikipedia&lt;/blockquote&gt;
Scaffolding is not meant to be used as is. It is meant to get you started!&lt;br /&gt;
In Rails3 you add controllers with a generator. You have a lot more options, below are just a few of them.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;$ rails g controller
Usage&lt;span style="color: #990000;"&gt;:&lt;/span&gt;
  rails generate controller NAME &lt;span style="color: #990000;"&gt;[&lt;/span&gt;action action&lt;span style="color: #990000;"&gt;]&lt;/span&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt;options&lt;span style="color: #990000;"&gt;]&lt;/span&gt;

Options&lt;span style="color: #990000;"&gt;:&lt;/span&gt;
  -e&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt;--template-engine&lt;span style="color: #990000;"&gt;=&lt;/span&gt;NAME&lt;span style="color: #990000;"&gt;]&lt;/span&gt;  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Template engine to be invoked&lt;/span&gt;&lt;/i&gt;
                                &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Default: erb&lt;/span&gt;&lt;/i&gt;
  -t&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt;--test-framework&lt;span style="color: #990000;"&gt;=&lt;/span&gt;NAME&lt;span style="color: #990000;"&gt;]&lt;/span&gt;   &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Test framework to be invoked&lt;/span&gt;&lt;/i&gt;
                                &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Default: test_unit&lt;/span&gt;&lt;/i&gt;

&lt;/tt&gt;&lt;/pre&gt;
As you can see it is possible to choose what template-engine you want to use, and exactly what actions you want to create, the view templates are created automatically with every action you create.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;$ rails g controller Customer index create
    conflict  app/controllers/customer_controller&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
      create  app/controllers/customer_controller&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
       route  get &lt;span style="color: red;"&gt;"customer/create"&lt;/span&gt;
       route  get &lt;span style="color: red;"&gt;"customer/index"&lt;/span&gt;
      invoke  erb
      create    app/views/customer
      create    app/views/customer/index&lt;span style="color: #990000;"&gt;.&lt;/span&gt;html&lt;span style="color: #990000;"&gt;.&lt;/span&gt;erb
      create    app/views/customer/create&lt;span style="color: #990000;"&gt;.&lt;/span&gt;html&lt;span style="color: #990000;"&gt;.&lt;/span&gt;erb
      invoke  test_unit
    create    test/functional/customer_controller_test&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
      invoke  helper
    create    app/helpers/customer_helper&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb
      invoke    test_unit
    create      test/unit/helpers/customer_helper_test&lt;span style="color: #990000;"&gt;.&lt;/span&gt;rb


If you want to create all the default actions you should instead invoke the scaffold_generator&lt;span style="color: #990000;"&gt;.&lt;/span&gt;

&lt;/tt&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;tt&gt;$ rails g scaffold_controller
Usage&lt;span style="color: #990000;"&gt;:&lt;/span&gt;
  rails generate scaffold_controller NAME &lt;span style="color: #990000;"&gt;[&lt;/span&gt;options&lt;span style="color: #990000;"&gt;]&lt;/span&gt;

&lt;/tt&gt;&lt;/pre&gt;
It will create all the default actions and the views that go with them.&lt;br /&gt;

The generated code is shown below. Again, you see the similarity between the two solutions. Rails, automatically generates support for both HTML and XML, making it easy to consume the data from other clients.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; FishController &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt; ApplicationController
  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# GET /fish&lt;/span&gt;&lt;/i&gt;
  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# GET /fish.xml&lt;/span&gt;&lt;/i&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; index
    &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; Fish&lt;span style="color: #990000;"&gt;.&lt;/span&gt;all

    respond_to &lt;b&gt;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;|&lt;/span&gt;format&lt;span style="color: #990000;"&gt;|&lt;/span&gt;
      format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;html &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# index.html.erb&lt;/span&gt;&lt;/i&gt;
      format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;xml  &lt;span style="color: red;"&gt;{&lt;/span&gt; render &lt;span style="color: #990000;"&gt;:&lt;/span&gt;xml &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: red;"&gt;}&lt;/span&gt;
    &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;

  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# GET /fish/1&lt;/span&gt;&lt;/i&gt;
  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# GET /fish/1.xml&lt;/span&gt;&lt;/i&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; show
    &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; Fish&lt;span style="color: #990000;"&gt;.&lt;/span&gt;find&lt;span style="color: #990000;"&gt;(&lt;/span&gt;params&lt;span style="color: #990000;"&gt;[:&lt;/span&gt;id&lt;span style="color: #990000;"&gt;])&lt;/span&gt;

    respond_to &lt;b&gt;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;|&lt;/span&gt;format&lt;span style="color: #990000;"&gt;|&lt;/span&gt;
      format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;html &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# show.html.erb&lt;/span&gt;&lt;/i&gt;
      format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;xml  &lt;span style="color: red;"&gt;{&lt;/span&gt; render &lt;span style="color: #990000;"&gt;:&lt;/span&gt;xml &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: red;"&gt;}&lt;/span&gt;
    &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;

  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# GET /fish/new&lt;/span&gt;&lt;/i&gt;
  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# GET /fish/new.xml&lt;/span&gt;&lt;/i&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; new
    &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; Fish&lt;span style="color: #990000;"&gt;.&lt;/span&gt;new

    respond_to &lt;b&gt;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;|&lt;/span&gt;format&lt;span style="color: #990000;"&gt;|&lt;/span&gt;
      format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;html &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# new.html.erb&lt;/span&gt;&lt;/i&gt;
      format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;xml  &lt;span style="color: red;"&gt;{&lt;/span&gt; render &lt;span style="color: #990000;"&gt;:&lt;/span&gt;xml &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: red;"&gt;}&lt;/span&gt;
    &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;

  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# GET /fish/1/edit&lt;/span&gt;&lt;/i&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; edit
    &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; Fish&lt;span style="color: #990000;"&gt;.&lt;/span&gt;find&lt;span style="color: #990000;"&gt;(&lt;/span&gt;params&lt;span style="color: #990000;"&gt;[:&lt;/span&gt;id&lt;span style="color: #990000;"&gt;])&lt;/span&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;

  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# POST /fish&lt;/span&gt;&lt;/i&gt;
  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# POST /fish.xml&lt;/span&gt;&lt;/i&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; create
    &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; Fish&lt;span style="color: #990000;"&gt;.&lt;/span&gt;new&lt;span style="color: #990000;"&gt;(&lt;/span&gt;params&lt;span style="color: #990000;"&gt;[:&lt;/span&gt;fish&lt;span style="color: #990000;"&gt;])&lt;/span&gt;

    respond_to &lt;b&gt;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;|&lt;/span&gt;format&lt;span style="color: #990000;"&gt;|&lt;/span&gt;
      &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;save
        format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;html &lt;span style="color: red;"&gt;{&lt;/span&gt; redirect_to&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;@fish&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;notice &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: red;"&gt;'Fish was successfully created.'&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;}&lt;/span&gt;
        format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;xml  &lt;span style="color: red;"&gt;{&lt;/span&gt; render &lt;span style="color: #990000;"&gt;:&lt;/span&gt;xml &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;status &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;created&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;location &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt; &lt;span style="color: red;"&gt;}&lt;/span&gt;
      &lt;b&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/b&gt;
        format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;html &lt;span style="color: red;"&gt;{&lt;/span&gt; render &lt;span style="color: #990000;"&gt;:&lt;/span&gt;action &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: red;"&gt;"new"&lt;/span&gt; &lt;span style="color: red;"&gt;}&lt;/span&gt;
        format&lt;span style="color: #990000;"&gt;.&lt;/span&gt;xml  &lt;span style="color: red;"&gt;{&lt;/span&gt; render &lt;span style="color: #990000;"&gt;:&lt;/span&gt;xml &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #009900;"&gt;@fish&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;errors&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;status &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;unprocessable_entity &lt;span style="color: red;"&gt;}&lt;/span&gt;
      &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
    &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
  &lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;
&lt;span style="color: #990000;"&gt;...&lt;/span&gt;
&lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;

&lt;h4&gt;Filters&lt;/h4&gt;
In Rails it is easy to create filters, that can be applied to specific actions.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; ItemsController &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt; ApplicationController
  before_filter &lt;span style="color: #990000;"&gt;:&lt;/span&gt;require_user_admin&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;only &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;destroy&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;update &lt;span style="color: #990000;"&gt;]&lt;/span&gt;
  before_filter &lt;span style="color: #990000;"&gt;:&lt;/span&gt;require_user&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;only &lt;span style="color: #990000;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;new&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;:&lt;/span&gt;create&lt;span style="color: #990000;"&gt;]&lt;/span&gt;
&lt;b&gt;&lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/b&gt;

&lt;/tt&gt;&lt;/pre&gt;
In ASP.NET MVC, the same thing can be accomplished by overriding &lt;b&gt;OnActionExecuting&lt;/b&gt;, in the controller.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;override &lt;span style="color: teal;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;OnActionExecuting&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;ActionExecutingContext&lt;/span&gt; filterContext&lt;span style="color: #990000;"&gt;)&lt;/span&gt;
&lt;span style="color: red;"&gt;{&lt;/span&gt;
    &lt;span style="color: teal;"&gt;var&lt;/span&gt; action &lt;span style="color: #990000;"&gt;=&lt;/span&gt; filterContext&lt;span style="color: #990000;"&gt;.&lt;/span&gt;ActionDescriptor&lt;span style="color: #990000;"&gt;.&lt;/span&gt;ActionName&lt;span style="color: #990000;"&gt;;&lt;/span&gt;
    &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;new&lt;/span&gt; List&lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;string&lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;span style="color: red;"&gt;"Delete"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: red;"&gt;"Edit"&lt;/span&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Contains&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;action&lt;span style="color: #990000;"&gt;))&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;
        &lt;b&gt;&lt;span style="color: black;"&gt;RequireUserAdmin&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;
    &lt;span style="color: red;"&gt;}&lt;/span&gt;
    &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Create"&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Equals&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;action&lt;span style="color: #990000;"&gt;))&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;
        &lt;b&gt;&lt;span style="color: black;"&gt;RequireUserAdmin&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;
    &lt;span style="color: red;"&gt;}&lt;/span&gt;
&lt;span style="color: red;"&gt;}&lt;/span&gt;

&lt;/tt&gt;&lt;/pre&gt;
The functionality may also be extracted into an ActionFilter, which can be applied to the controller or an individual method via an Attribute.&lt;br /&gt;
&lt;pre&gt;&lt;tt&gt;&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;RequireUserAdmin&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Delete"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: red;"&gt;"Edit"&lt;/span&gt;&lt;span style="color: #990000;"&gt;)]&lt;/span&gt;
&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;RequireUser&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Create"&lt;/span&gt;&lt;span style="color: #990000;"&gt;)]&lt;/span&gt;
public &lt;span style="color: teal;"&gt;class&lt;/span&gt; CustomersController &lt;
