Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

4121 lines (3061 sloc) 300.448 kb
<rss version="2.0">
<channel>
<title>Nodeblogs.com Feed</title>
<link/>http://www.nodeblogs.com/feed/blogs
<description>Nodeblogs aggregated feed</description>
<pubDate>Fri May 21 2010 08:22:19 GMT+0000 (UTC)</pubDate>
<generator>http://github.com/christkv/node-blogs</generator>
<language>en</language>
<item>
<title>Buffers not the way for mongodb :(</title>
<category>m,o,n,g,o,d,b,,,n,o,d,e,j,s,,,d,e,v,e,l,o,p,m,e,n,t,,,j,a,v,a,s,c,r,i,p,t</category>
<author></author>
<guid>http://christiankvalheim.com/post/612792033</guid>
<link/>http://christiankvalheim.com/post/612792033
<description>&amp;lt;p&amp;gt;I have been working on trying to get the speed up on the mongodb nodejs driver and buffers looked very promising so I decided to attempt to optimize the incoming data streams using buffers the theory being that I would avoid a lot of excessive copying of data back and forth in V8 due to string manipulation.
I had a mini benchmark
&amp;lt;a href=&quot;http://github.com/christkv/node-mongodb-native/blob/master/benchmark/streaming_benchmark.js&quot;&amp;gt;benchmark/streaming_benchmark.js&amp;lt;/a&amp;gt;
that was heavy on reading that gave the following results on my macbook pro on the string based version.
&amp;lt;pre&amp;gt;
save recs: 10.02seconds
recs:10000 :: 0.59seconds
recs:20000 :: 1.206seconds
recs:30000 :: 1.829seconds
recs:40000 :: 2.471seconds
recs:50000 :: 3.119seconds
recs:60000 :: 3.745seconds
recs:70000 :: 4.393seconds
recs:80000 :: 5seconds
recs:90000 :: 5.596seconds
recs:100000 :: 6.164seconds
&amp;lt;/pre&amp;gt;
The refactored version using buffers instead of strings and taking advantage that the socket returns a buffer turned out the following numbers.
&amp;lt;pre&amp;gt;
save recs: 8.882seconds
recs:10000 :: 1.719seconds
recs:20000 :: 3.414seconds
recs:30000 :: 5.181seconds
recs:40000 :: 6.949seconds
recs:50000 :: 8.706seconds
recs:60000 :: 10.501seconds
recs:70000 :: 12.235seconds
recs:80000 :: 13.967seconds
recs:90000 :: 15.696seconds
recs:100000 :: 17.423seconds
&amp;lt;/pre&amp;gt;
It’s pretty obvious a no-go at this stage. I suspect that the overhead of interacting with the buffer object is negating any gain in performance from avoiding the garbage collector in v8 but that’s a wild guess from my side at this point.
I did however change the binary storage object to buffers which dropped the memory consumption off the gridstore on large files a fair amount and stopped it from crashing.
However the lesson from that is. Don’t read a 100 MB file into memory and write it out to mongodb in one go. Read it in chunks using fs.read instead of fs.readFile.
I’m gona put the buffer refactoring on hold but if you want to check it out and maybe lend a hand towards understanding why it is so much slower then take a look at the branch
&amp;lt;a href=&quot;http://github.com/christkv/node-mongodb-native/tree/buffers_buffers_buffers&quot;&amp;gt;
&amp;lt;a href=&quot;http://github.com/christkv/node-mongodb-native/tree/buffers_buffers_buffers&quot;&amp;gt;http://github.com/christkv/node-mongodb-native/tree/buffers_buffers_buffers&amp;lt;/a&amp;gt;
&amp;lt;/a&amp;gt;
Cheers&amp;lt;/p&amp;gt;</description>
<pubDate>Wed May 19 2010 10:00:13 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Streaming UTF-8 (with node.js)</title>
<category></category>
<author>felix@debuggable.com</author>
<guid>http://www.debuggable.com/posts/streaming-utf-8-with-node-js:4bf28e8b-a290-432f-a222-11c1cbdd56cb</guid>
<link/>http://feedproxy.google.com/~r/debuggable/~3/5B_DXu-vkv0/streaming-utf-8-with-node-js:4bf28e8b-a290-432f-a222-11c1cbdd56cb
<description>&amp;lt;p&amp;gt;&amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Utf-8#Description&quot;&amp;gt;UTF-8&amp;lt;/a&amp;gt; is a variable-length character encoding for &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Unicode&quot;&amp;gt;Unicode&amp;lt;/a&amp;gt;. This text is encoded in UTF-8, so the characters you are reading can consist of 1 to 4 bytes. As long as the characters fit within the ASCII range (0-127), there is exactly 1 byte used per character.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;But if I want to express a character outside the ASCII range, such as '¢', I need more bytes. The character '¢' for example consists of: 0xC2 and 0xA2. The first byte, 0xC2, indicates that '¢' is a 2-byte character. This is easy to understand if you look at the binary representation of 0xC2:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;11000010
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;As you can see, the bit sequence begins with '110', which as per the UTF-8 specification means: &quot;2 byte character ahead!&quot;. Another character such as '€' (0xE2, 0x82, 0xAC) would work the same way. The first byte, 0xE2, looks like this in binary:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;11100010
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;The prefix '1110' specifies that there are 3 bytes forming the current character. More exotic characters may even start with '11110', which indicates a 4 byte character.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;As you can guess, UTF-8 text is not trivial to stream. Networks and file systems are not UTF-8 aware, so they will often split a chunk of text in the middle of a character.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;To make sure you don't process a partial character, you have to analyze the last 3 bytes of any given chunk in your stream to check for the bit-prefixes that are used to announce a multibyte character. If you detect an incomplete character, you need to buffer the bytes you have for it, and then prepend them to the next chunk that comes in.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;This way you can completely avoid breaking apart multibyte characters within a UTF-8 text, while still getting great performance and memory usage (only the last 3 bytes need checking / buffering).&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;As of yesterday, &amp;lt;a href=&quot;http://nodejs.org/&quot;&amp;gt;node.js&amp;lt;/a&amp;gt;'s net / http modules are now fully UTF-8 safe, thanks to the streaming Utf8Decoder (undocumented, API may change) you can see below:&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;div class=&quot;clear&quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&quot;code debuggable_sh_js&quot; style=&quot;white-space: wrap;white-space: nowrap;&quot;&amp;gt;
&amp;lt;span class=&quot;kw2&quot;&amp;gt;var&amp;lt;/span&amp;gt; Buffer = require&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;st0&quot;&amp;gt;'buffer'&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;Buffer&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;lt;span class=&quot;kw2&quot;&amp;gt;var&amp;lt;/span&amp;gt; Utf8Decoder = exports.&amp;lt;span class=&quot;me1&quot;&amp;gt;Utf8Decoder&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;kw2&quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charBuffer&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;kw2&quot;&amp;gt;new&amp;lt;/span&amp;gt; Buffer&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;nu0&quot;&amp;gt;4&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charReceived&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
Utf8Decoder.&amp;lt;span class=&quot;me1&quot;&amp;gt;prototype&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;kw1&quot;&amp;gt;write&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;kw2&quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;buffer&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw2&quot;&amp;gt;var&amp;lt;/span&amp;gt; charStr = &amp;lt;span class=&quot;st0&quot;&amp;gt;''&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// if our last write ended with an incomplete multibyte character&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// determine how many remaining bytes this buffer has to offer for this char&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw2&quot;&amp;gt;var&amp;lt;/span&amp;gt; i = &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt; &amp;amp;gt;= &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt; - &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charReceived&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; ? &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt; - &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charReceived&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; : buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// add the new bytes to the char buffer&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;copy&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charBuffer&amp;lt;/span&amp;gt;, &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charReceived&amp;lt;/span&amp;gt;, &amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;, i&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charReceived&amp;lt;/span&amp;gt; += i;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charReceived&amp;lt;/span&amp;gt; &amp;amp;lt; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// still not enough chars in this buffer? wait for more ...&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;return&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// get the character that was split&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; charStr = &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charBuffer&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;slice&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;, &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;toString&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charReceived&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;i == buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// if there are no more bytes in this buffer, just emit our char&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;onString&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;charStr&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;return&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// otherwise cut of the characters end from the beginning of this buffer&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; buffer = buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;slice&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;i, buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// determine how many bytes we have to check at the end of this buffer&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw2&quot;&amp;gt;var&amp;lt;/span&amp;gt; i = &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt; &amp;amp;gt;= &amp;lt;span class=&quot;nu0&quot;&amp;gt;3&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; ? &amp;lt;span class=&quot;nu0&quot;&amp;gt;3&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; : buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// figure out if one of the last i bytes of our buffer announces an incomplete char&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;for&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;; i &amp;amp;gt; &amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;; i--&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; c = buffer&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#91;&amp;lt;/span&amp;gt;buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt; - i&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#93;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// See http://en.wikipedia.org/wiki/UTF-8#Description&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// 110XXXXX&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;i == &amp;lt;span class=&quot;nu0&quot;&amp;gt;1&amp;lt;/span&amp;gt; &amp;amp;amp;&amp;amp;amp; c &amp;amp;gt;&amp;amp;gt; &amp;lt;span class=&quot;nu0&quot;&amp;gt;5&amp;lt;/span&amp;gt; == 0x06&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;nu0&quot;&amp;gt;2&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;break&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// 1110XXXX&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;i &amp;amp;lt;= &amp;lt;span class=&quot;nu0&quot;&amp;gt;2&amp;lt;/span&amp;gt; &amp;amp;amp;&amp;amp;amp; c &amp;amp;gt;&amp;amp;gt; &amp;lt;span class=&quot;nu0&quot;&amp;gt;4&amp;lt;/span&amp;gt; == 0x0E&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;nu0&quot;&amp;gt;3&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;break&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// 11110XXX&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;i &amp;amp;lt;= &amp;lt;span class=&quot;nu0&quot;&amp;gt;3&amp;lt;/span&amp;gt; &amp;amp;amp;&amp;amp;amp; c &amp;amp;gt;&amp;amp;gt; &amp;lt;span class=&quot;nu0&quot;&amp;gt;3&amp;lt;/span&amp;gt; == 0x1E&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt; = &amp;lt;span class=&quot;nu0&quot;&amp;gt;4&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;break&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;!&amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charLength&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// no incomplete char at the end of this buffer, emit the whole thing&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;onString&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;charStr+buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;toString&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;return&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// buffer the incomplete character bytes we got&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;copy&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charBuffer&amp;lt;/span&amp;gt;, &amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;, buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt; - i, buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;charReceived&amp;lt;/span&amp;gt; = i;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt; - i &amp;amp;gt; &amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// buffer had more bytes before the incomplete char, emit them&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;onString&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;charStr+buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;slice&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;nu0&quot;&amp;gt;0&amp;lt;/span&amp;gt;, buffer.&amp;lt;span class=&quot;me1&quot;&amp;gt;length&amp;lt;/span&amp;gt; - i&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;toString&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;kw1&quot;&amp;gt;else&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;kw1&quot;&amp;gt;if&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;charStr&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;co1&quot;&amp;gt;// or just emit the charStr if any&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;amp;nbsp; &amp;lt;span class=&quot;kw1&quot;&amp;gt;this&amp;lt;/span&amp;gt;.&amp;lt;span class=&quot;me1&quot;&amp;gt;onString&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;charStr&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;;&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;I feel like this implementation could still be somewhat simplified, so if you have any suggestions or comments, please let me know!&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;--fg&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;PS: Another buffer-based project I'm working on is a fast multipart parser - stay tuned for another post!&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;img style=&quot;display: none;&quot; src=&quot;http://www.debuggable.com/posts/tick/4bf28e8b-a290-432f-a222-11c1cbdd56cb&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;img src=&quot;http://feeds.feedburner.com/~r/debuggable/~4/5B_DXu-vkv0&quot; height=&quot;1&quot; width=&quot;1&quot;/&amp;gt;</description>
<pubDate>Tue May 18 2010 13:03:23 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>A simple insert and query using node.js mongodb driver</title>
<category>m,o,n,g,o,d,b,,,n,o,d,e,j,s,,,s,i,m,p,l,e,,,t,u,t,o,r,i,a,l,,,j,a,v,a,s,c,r,i,p,t</category>
<author></author>
<guid>http://christiankvalheim.com/post/596160094</guid>
<link/>http://christiankvalheim.com/post/596160094
<description>Let’s start with a simple nodejs mongo example opening the db, inserting a document, querying for the document by a field, changing the document and saving the updated document back to mongo before closing the database.
&amp;lt;pre&amp;gt;&amp;lt;code class=&quot;javascript&quot;&amp;gt;
// Let's get the 'Classes' used for the driver
var Db = require('mongodb').Db,
Server = require('mongodb').Server;
// Open a connection to your mongodb server for the database 'simple_tutorial'
// pass in the option for auto_reconnect (in case the server dies the connection
// will restart
new Db('simple_tutorial',
new Server(&quot;127.0.0.1&quot;, 27017, {auto_reconnect: false}), {}).open(function(err, db) {
// Let's grab a collection/table
db.collection('documents', function(err, collection) {
// Now's time to insert our brilliant document for permanent storage
collection.insert({awesome:1, info:{type:'binary'}}, function(err, doc) {
// The document is inserted asynchronous so control is instantly returned to
// the calling code thus allowing high write speed, the unique id is actually
// assigned by the client driver not the mongodb server. you can override
// the default key factory (see integration_tests.js that comes with the)
// the driver
// Let's fetch the document using the collection.findOne method
collection.findOne({awesome:1}, function(err, document) {
// Let's change the info field to something else and update the object
// in the collection (you can use the collection.save method if you want
// to update using the document id as the identifier otherwise you have
// to pass in the query that selects the document you wish to update
document.info = {type:'silly'};
collection.update({awesome:1}, document, function(err, document) {
// Document updated in the database, let's finish off by closing
// the db connection and thus ending the execution
db.close();
});
});
});
});
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;
That’s a very simple little introduction to the use of the ‘VERY’ basic functionality of the node-mongodb-native driver you can find at
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
&amp;lt;a href=&quot;http://github.com/christkv/node-mongodb-native&quot;&amp;gt;&amp;lt;a href=&quot;http://github.com/christkv/node-mongodb-native&quot;&amp;gt;http://github.com/christkv/node-mongodb-native&amp;lt;/a&amp;gt;&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
I hope to do more in-depth topics going forward or answers to questions I’m asked by people using the driver to write they applications.
&amp;lt;/p&amp;gt;</description>
<pubDate>Thu May 13 2010 21:38:41 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Getting started</title>
<category></category>
<author></author>
<guid>http://christiankvalheim.com/post/595875746</guid>
<link/>http://christiankvalheim.com/post/595875746
<description>&amp;lt;p&amp;gt;Hi&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;I finally got my ass out of my chair and signed up for a blog. Over the next couple of weeks I’ll be posting a lot of information and hopefully tips and tricks on how to use the nodejs open source projects I have published or are interested in.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Once in a while other musings on software development and working with developers will probably be posted but that will be more of the exception.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;I also have a small project that I’m currently working on that I’m thinking of as a long term business idea. I’m gona try something new. Instead of aiming for the 1 Million dollar startup idea I’m going to aim for a service that will do what I need for it to do and that can be a payed subscription service in the future. Focus will also be on creating a real community around the product and maybe even look at some new ways of organizing the use of income from the project. Hopefully it can be a mom-and-pop business that I will focus on for the rest of my working life.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;I believe our business would be much better served if we had more 2-3 people shops supporting products long term as a passionate private business instead of aiming for the lottery payout of a venture-backed startup. It also puts a perspective on the work that means you are not rushing like crazy to build features and focus on the long term viability of the business and product.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Cheers&amp;lt;/p&amp;gt;</description>
<pubDate>Thu May 13 2010 19:20:42 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Understanding node.js</title>
<category></category>
<author>felix@debuggable.com</author>
<guid>http://www.debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb</guid>
<link/>http://feedproxy.google.com/~r/debuggable/~3/qf8IvkdIyLA/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb
<description>&amp;lt;p&amp;gt;&amp;lt;a href=&quot;http://nodejs.org/&quot;&amp;gt;Node.js&amp;lt;/a&amp;gt; has generally caused two reactions in people I've introduced it to. Basically people either &quot;got it&quot; right away, or they ended up being very confused.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;If you have been in the second group so far, here is my attempt to explain node:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;It is a command line tool. You download a tarball, compile and install the source.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;It let's you run JavaScript programs by typing 'node my_app.js' in your terminal.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;The JS is executed by the &amp;lt;a href=&quot;http://code.google.com/p/v8/&quot;&amp;gt;V8 javascript engine&amp;lt;/a&amp;gt; (the thing that makes Google Chrome so fast).&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Node provides a JavaScript API to access the network and file system&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;But I can do everything I need in: ruby, python, php, java, ... !&quot;.&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;I hear you. And you are right! Node is no freaking unicorn that will come and do your work for you, sorry. It's just a tool, and it probably won't replace your regular tools completely, at least not for now.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;Get to the point!&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Alright, I will. Node is basically very good when you need to do several things at the same time. Have you ever written a piece of code and said &quot;I wish this would run in parallel&quot;? Well, in node everything runs in parallel, except your code.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;Huh?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;That's right, &amp;lt;em&amp;gt;everything runs in parallel, except your code&amp;lt;/em&amp;gt;. To understand that, imagine your code is the king, and node is his army of servants.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;The day starts by one servant waking up the king and asking him if he needs anything. The king gives the servant a list of tasks and goes back to sleep a little longer. The servant now distributes those tasks among his colleagues and they get to work.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Once a servant finishes a task, he lines up outside the kings quarter to report. The king lets one servant in at a time, and listens to things he reports. Sometimes the king will give the servant more tasks on the way out.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Life is good, for the king's servants carry out all of his tasks in parallel, but only report with one result at a time, so the king can focus. *&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;That's fantastic, but could you quit the silly metaphor and speak geek to me?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Sure. A simple node program may look like this:&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;div class=&quot;clear&quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&quot;code debuggable_sh_js&quot; style=&quot;white-space: wrap;white-space: nowrap;&quot;&amp;gt;
&amp;lt;span class=&quot;kw2&quot;&amp;gt;var&amp;lt;/span&amp;gt; fs = require&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;st0&quot;&amp;gt;'fs'&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; , sys = require&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;st0&quot;&amp;gt;'sys'&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
fs.&amp;lt;span class=&quot;me1&quot;&amp;gt;readFile&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;st0&quot;&amp;gt;'treasure-chamber-report.txt'&amp;lt;/span&amp;gt;, &amp;lt;span class=&quot;kw2&quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;report&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; sys.&amp;lt;span class=&quot;me1&quot;&amp;gt;puts&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;st0&quot;&amp;gt;&amp;amp;quot;oh, look at all my money: &amp;amp;quot;&amp;lt;/span&amp;gt;+report&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;br /&amp;gt;
fs.&amp;lt;span class=&quot;me1&quot;&amp;gt;writeFile&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;st0&quot;&amp;gt;'letter-to-princess.txt'&amp;lt;/span&amp;gt;, &amp;lt;span class=&quot;st0&quot;&amp;gt;'...'&amp;lt;/span&amp;gt;, &amp;lt;span class=&quot;kw2&quot;&amp;gt;function&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt; &amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#123;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;
&amp;amp;nbsp; sys.&amp;lt;span class=&quot;me1&quot;&amp;gt;puts&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#40;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;st0&quot;&amp;gt;&amp;amp;quot;can't wait to hear back from her!&amp;amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;br /&amp;gt;
&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#125;&amp;lt;/span&amp;gt;&amp;lt;span class=&quot;br0&quot;&amp;gt;&amp;amp;#41;&amp;lt;/span&amp;gt;;&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Your code gives node the two tasks to read and write a file, and then goes to sleep. Once node has completed a task, the callback for it is fired. But there can only be one callback firing at the same time. Until that callback has finished executing, all other callbacks have to wait in line. In addition to that, there is no guarantee on the order in which the callbacks will fire.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;So I don't have to worry about code accessing the same data structures at the same time?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;You got it! That's the entire beauty of JavaScripts single-threaded / event loop design!&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;Very nice, but why should I use it?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;One reason is efficiency. In a web application, your main response time cost is usually the sum of time it takes to execute all your database queries. With node, you can execute all your queries at once, reducing the response time to the duration it takes to execute the slowest query.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Another reason is JavaScript. You can use node to share code between the browser and your backend. JavaScript is also on its way to become a really universal language. No matter if you did python, ruby, java, php, ... in the past, you've probably picked up some JS along the way, right?&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;And the last reason is raw speed. V8 is constantly pushing the boundaries in being one of the fastest dynamic language interpreters on the planet. I can't think of any other language that is being pushed for speed as aggressively as JavaScript is right now. In addition to that, node's I/O facilities are really light weight, bringing you as close to fully utilizing your system's full I/O capacities as possible.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;So you are saying I should write all my apps in node from now on?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Yes and no. Once you start to swing the node hammer, everything is obviously going to start looking like a nail. But if you're working on something with a deadline, you might want to base your decision on:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;Are low response times / high concurrency important? Node is really good at that.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;How big is the project? Small projects should be fine. Big projects should evaluate carefully (available libraries, resources to fix a bug or two upstream, etc.).&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;Does node run on Windows?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;No. If you are on windows, you need to run a virtual machine (I recommend &amp;lt;a href=&quot;http://www.virtualbox.org/&quot;&amp;gt;VirtualBox&amp;lt;/a&amp;gt;) with Linux. Windows support for node is planned, but don't hold your breath for the next few months unless you want to help with the port.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;Can I access the DOM in node?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Excellent question! No, the DOM is a browser thingy, and node's JS engine (V8) is thankfully totally separate from all that mess. However, there are people working on implementing &amp;lt;a href=&quot;http://www.yuiblog.com/blog/2010/04/09/node-js-yui-3-dom-manipulation-oh-my/&quot;&amp;gt;the DOM as a node module&amp;lt;/a&amp;gt;, which may open very exciting possibilities such as unit testing client-side code.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;Isn't event driven programming really hard?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;That depends on you. If you already learned how to juggle AJAX calls and user events in the browser, getting used to node shouldn't be a problem.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Either way, test driven development can really help you to come up with maintainable designs.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;Who is using it?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;There is a small / incomplete list in the &amp;lt;a href=&quot;http://wiki.github.com/ry/node&quot;&amp;gt;node wiki&amp;lt;/a&amp;gt; (scroll to &quot;Companies using Node&quot;). &amp;lt;a href=&quot;http://www.yuiblog.com/blog/2010/04/09/node-js-yui-3-dom-manipulation-oh-my/&quot;&amp;gt;Yahoo&amp;lt;/a&amp;gt; is experimenting with node for YUI, &amp;lt;a href=&quot;http://www.plurk.com/&quot;&amp;gt;Plurk&amp;lt;/a&amp;gt; is using it for massive comet and Paul Bakaus (of jQuery UI fame) is building a &amp;lt;a href=&quot;http://ajaxian.com/archives/aves-game-engine&quot;&amp;gt;mind-blowing game engine&amp;lt;/a&amp;gt; that has some node in the backend. &amp;lt;a href=&quot;http://www.joyent.com/&quot;&amp;gt;Joyent&amp;lt;/a&amp;gt; has hired Ryan Dahl (the creator of node) and heavily sponsors the development.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Oh, and Heroku just announced (experimental ) &amp;lt;a href=&quot;http://blog.heroku.com/archives/2010/4/28/node_js_support_experimental/&quot;&amp;gt;hosting support for node.js&amp;lt;/a&amp;gt; as well.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;&quot;Where can I learn more?&quot;&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Tim Caswell is running the excellent &amp;lt;a href=&quot;http://howtonode.org/&quot;&amp;gt;How To Node&amp;lt;/a&amp;gt; blog. Follow &amp;lt;a href=&quot;http://search.twitter.com/search?q=%23nodejs&quot;&amp;gt;#nodejs&amp;lt;/a&amp;gt; on twitter. Subscribe to the &amp;lt;a href=&quot;http://groups.google.com/group/nodejs&quot;&amp;gt;mailing list&amp;lt;/a&amp;gt;. And come and hang out in the IRC channel, &amp;lt;em&amp;gt;#node.js&amp;lt;/em&amp;gt; (yes, the dot is in the name). We're close to hitting the 200 lurker-mark there soon : ).&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;I'll also continue to write articles here on &amp;lt;a href=&quot;http://debuggable.com/&quot;&amp;gt;debuggable.com&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;That's it for now. Feel free to comment if you have more questions!&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;--fg&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;*: The metaphor is obviously a simplification, but if it's hard to find a counterpart for the concept of non-blocking in reality.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;img style=&quot;display: none;&quot; src=&quot;http://www.debuggable.com/posts/tick/4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;img src=&quot;http://feeds.feedburner.com/~r/debuggable/~4/qf8IvkdIyLA&quot; height=&quot;1&quot; width=&quot;1&quot;/&amp;gt;</description>
<pubDate>Thu Apr 29 2010 13:06:08 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Quitting open source</title>
<category></category>
<author>felix@debuggable.com</author>
<guid>http://www.debuggable.com/posts/quitting-open-source:4bb448b6-6414-45a3-a282-16c7cbdd56cb</guid>
<link/>http://feedproxy.google.com/~r/debuggable/~3/BVubEW8t1RM/quitting-open-source:4bb448b6-6414-45a3-a282-16c7cbdd56cb
<description>&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Update:&amp;lt;/strong&amp;gt; Yes, this of course was an April fools joke : )&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;This is a decision that has not been easy for us. Over the years, Tim and I build our reputation and company on the basis of open source. For a long time we worked on &amp;lt;a href=&quot;http://cakephp.org/&quot;&amp;gt;CakePHP&amp;lt;/a&amp;gt;, and more recently I became very involved with &amp;lt;a href=&quot;http://nodejs.org/&quot;&amp;gt;node.js&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Generally, open source has been very good to us. We learned a lot about programming, collaborated with great people and, thanks to our clients, made payroll consistently.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;But sometimes, even if things are good, you have to evaluate if they are aligned with your true goals. And today, we finally decided they are not. Our goals and the nature of open source are in fundamental conflict.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;What changed? Well, when we initially started debuggable, our goal was to build commercial web applications and make a living from that. But it turns out, that is actually really hard.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;37signals may wash your head about getting real until it comes off, but the truth is:&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;You will not build a product like basecamp with a limit of 10h / week. And you certainly will not, let me stress that, develop an open source technology like Ruby on Rails along the way, which will then help you promote your product(s). 37signals either got insanely lucky, or they are glorifying their story after the fact. It is probably both.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;This leads back to our decision. We have concluded, that in order to reach our goals for 2010, we need more time. It is not really possible to cut on client work, since we've got bills to pay. So instead, we will drastically cut on our open source involvement.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Beginning today, we will only work on open source, if we actually really need a critical bug fixed, and the maintainer of the project refuses to fix it for us. We will only send those bug fixes upstream, if the patches are big enough so it would be more difficult for us to maintain them privately.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;We estimate that this will free us 20 hours / week. Those hours, for now, will be used to finally get &amp;lt;a href=&quot;http://transloadit.com/&quot;&amp;gt;transloadit.com&amp;lt;/a&amp;gt; out of the testing phase. At the same time, we are evaluating a more radical technology change. We recently developed our first native iPhone application for a client, and it is a truly great plattform. Also the iPad seems like a great opportunity we shouldn't miss. So I wouldn't be surprised if Tim and I would be moving to the App Store ecosystem at some point.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;So fare well, open source community. We are sorry we can longer be a part. Our website will be updated to reflect our new philosophy by tomorrow.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;-- Felix &amp;amp;amp; Tim&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;img style=&quot;display: none;&quot; src=&quot;http://www.debuggable.com/posts/tick/4bb448b6-6414-45a3-a282-16c7cbdd56cb&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;img src=&quot;http://feeds.feedburner.com/~r/debuggable/~4/BVubEW8t1RM&quot; height=&quot;1&quot; width=&quot;1&quot;/&amp;gt;</description>
<pubDate>Thu Apr 01 2010 07:38:17 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Hello Node!</title>
<category></category>
<author>tim@creationix.com (Tim Caswell)</author>
<guid>http://howtonode.org/hello-node</guid>
<link/>http://howtonode.org/hello-node
<description>&amp;lt;p&amp;gt;In programming literature it has become the standard to create a hello world program as the first example. This article will go through a few simple hello world type examples with everything from simple terminal output to an http server that uses an external framework for some semantic sugar.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Then we'll shift gears and go through a real example that teaches enough to get you up on your feet writing your own web application using node.JS.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Hello World Examples&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Here are four simple hello world examples. The comments in the code explain how the code works and the text around it explain what it does and how to test it.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Hello Console&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;This example is about as plain as it can get. It prints the words &quot;Hello World&quot; to the terminal.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;hello-node/hello-console.js&quot; class=&quot;code-link&quot;&amp;gt;hello-console.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Load the sys module since we want to write to the terminal
var sys = require('sys');
// Call the puts function on the sys module.
sys.puts(&amp;amp;quot;Hello World&amp;amp;quot;);&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;Hello World
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;You can run this by putting it in a file called &quot;hello-console.js&quot; and running it with &amp;lt;code&amp;gt;node hello-console.js&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Hello HTTP&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;I'd guess that while it's not the only use case for node.JS, most people are using it as a web application platform. So the next example will be a simple HTTP server that responds to every request with the plain text message &quot;Hello World&quot;&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;hello-node/hello-http.js&quot; class=&quot;code-link&quot;&amp;gt;hello-http.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Load the sys module for console writing.
var sys = require('sys');
// Load the http module to create an http server.
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
response.writeHead(200, {&amp;amp;quot;Content-Type&amp;amp;quot;: &amp;amp;quot;text/plain&amp;amp;quot;});
response.write(&amp;amp;quot;Hello World\n&amp;amp;quot;);
response.close();
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
sys.puts(&amp;amp;quot;Server running at http://127.0.0.1:8000/&amp;amp;quot;);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;h2&amp;gt;Hello TCP&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Node also makes an excellent TCP server, and here is an example that responds to all TCP connections with the message &quot;Hello World&quot; and then closes the connection.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;hello-node/hello-tcp.js&quot; class=&quot;code-link&quot;&amp;gt;hello-tcp.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Load the sys module for console writing.
var sys = require('sys');
// Load the net module to create a tcp server.
var net = require('net');
// Setup a tcp server
var server = net.createServer(function (socket) {
// Every time someone connects, tell them hello and then close the connection.
socket.addListener(&amp;amp;quot;connect&amp;amp;quot;, function () {
sys.puts(&amp;amp;quot;Connection from &amp;amp;quot; + socket.remoteAddress);
socket.write(&amp;amp;quot;Hello World\n&amp;amp;quot;);
socket.end();
});
});
// Fire up the server bound to port 7000 on localhost
server.listen(7000, &amp;amp;quot;localhost&amp;amp;quot;);
// Put a friendly message on the terminal
sys.puts(&amp;amp;quot;TCP server listening on port 7000 at localhost.&amp;amp;quot;);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;h2&amp;gt;Hello Router&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Often you won't be using the node built-in libraries because they are designed to be very low level. This makes node quick, nimble, and easy to maintain, but is usually not enough to get started on a real world application. My first node framework is &amp;lt;code&amp;gt;node-router&amp;lt;/code&amp;gt;. This example shows an HTTP server that responds with &quot;Hello World&quot; to all requests to &quot;/&quot; and responds with a 404 error to everything else.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;hello-node/hello-router.js&quot; class=&quot;code-link&quot;&amp;gt;hello-router.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Load the node-router library by creationix
var server = require('node-router').getServer();
// Configure our HTTP server to respond with Hello World the root request
server.get(&amp;amp;quot;/&amp;amp;quot;, function (request, response) {
response.simpleText(200, &amp;amp;quot;Hello World!&amp;amp;quot;);
});
// Listen on port 8080 on localhost
server.listen(8000, &amp;amp;quot;localhost&amp;amp;quot;);&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;In order to test this, you will need to install the &amp;lt;code&amp;gt;node-router&amp;lt;/code&amp;gt; library. There are two ways to do this. You can either install it into a path that node recognizes (I create a symlink into ~/.node_libraries) or put the &amp;lt;code&amp;gt;node-router.js&amp;lt;/code&amp;gt; file in your application and reference it locally. See the &amp;lt;a href=&quot;http://nodejs.org/api.html#_modules&quot;&amp;gt;node docs on modules&amp;lt;/a&amp;gt; for more details on how modules work.&amp;lt;/p&amp;gt;
&amp;lt;h1&amp;gt;Installing Libraries&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;I'll install the following libraries that are common to my projects:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://github.com/creationix/node-router&quot;&amp;gt;node-router&amp;lt;/a&amp;gt; - Wraps the built-in http library with many convenience functions like request routing and message body decoding.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://github.com/creationix/haml-js&quot;&amp;gt;haml-js&amp;lt;/a&amp;gt; - Template engine that compiles HAML templates into HTML&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://github.com/creationix/proto&quot;&amp;gt;proto&amp;lt;/a&amp;gt; - Baby library that adds some useful stuff to Object.prototype&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;You can install these however you please, but here is how I'd do it. The following code will clone the four libraries and install them into your local node library search path:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;hello-node/install.sh&quot; class=&quot;code-link&quot;&amp;gt;install.sh&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir ~/NodeLibs
cd ~/NodeLibs
git clone git://github.com/creationix/node-router.git
git clone git://github.com/creationix/haml-js.git
git clone git://github.com/creationix/proto.git
mkdir ~/.node_libraries
cd ~/.node_libraries
ln -s ~/NodeLibs/*/lib/* ./
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;That's it for now, this article was going to explain more, but it seems it got lost and fell through the cracks. Hopefully this will help you get started working with node.JS, it's a blast!.&amp;lt;/p&amp;gt;</description>
<pubDate>Mon Mar 22 2010 15:55:41 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Facebook Connect with Node</title>
<category></category>
<author>info@dominiek.com (Dominiek ter Heide)</author>
<guid>http://howtonode.org/facebook-connect</guid>
<link/>http://howtonode.org/facebook-connect
<description>&amp;lt;p&amp;gt;A big part of building a new web application is repurposing common patterns, one such pattern is the ability for users to sign in and out. One way of solving this quickly is by using Facebook Connect. &amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Background&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Unlike some APIs, the Facebook API is very Javascript friendly, but unfortunately it can be very time consuming to go through the maze of misdirected Facebook documentation. So in order to make Facebook integration quick and easy, I've wrapped a lot of under-the-hood code into a plugin called &amp;lt;a href=&quot;http://github.com/dominiek/node-facebook&quot;&amp;gt;node-facebook&amp;lt;/a&amp;gt;. This plugin also provides examples and routines to get your Facebook Canvas application running quickly with Node, however, this article will focus on the FB Connect part.&amp;lt;/p&amp;gt;
&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;Facebook's developer tools are increasingly going into the direction of more Javascript on the client-side. I also have a strong preference of offloading certain logic to the client-side. This article will also attempt to follow &amp;lt;a href=&quot;http://synaptify.com/?p=613702&quot;&amp;gt;that direction&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&amp;lt;h2&amp;gt;Communication&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;As you can see in this totally unnecessary diagram, most of the integration takes place on the client-side:&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;img src=&quot;http://github.com/dominiek/node-facebook/raw/master/doc/communication.png&quot; alt=&quot;Awesome Diagram&quot; title=&quot;Awesome Diagram&quot; /&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Dependencies&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;Note: For this article I've been using NodeJS version 0.1.31 and Express version 0.7.1&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;You need to install both &amp;lt;a href=&quot;http://nodejs.org&quot;&amp;gt;NodeJS&amp;lt;/a&amp;gt; and the &amp;lt;a href=&quot;http://github.com/visionmedia/express&quot;&amp;gt;Express Web Framework&amp;lt;/a&amp;gt;. Assuming you've installed NodeJS, you can easily include express into your Git project by adding a submodule:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir -p lib/support
git submodule add git://github.com/visionmedia/express.git lib/support/express
cd lib/support/express
git submodule init
git submodule update
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Second, you need to include &amp;lt;a href=&quot;http://github.com/brainfucker/hashlib&quot;&amp;gt;Hashlib&amp;lt;/a&amp;gt; into your project and compile it. Hashlib is a library that provides cryptographic routines like MD5:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;git submodule add git://github.com/brainfucker/hashlib.git lib/support/hashlib
cd lib/support/hashlib
make
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h2&amp;gt;1. Registering your Facebook Application&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;In order to use Facebook Connect, you need to &amp;lt;a href=&quot;http://facebook.com/developer&quot;&amp;gt;register a new Facebook application&amp;lt;/a&amp;gt; and set the FB Connect URL to the root of your application:&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;img src=&quot;http://github.com/dominiek/node-facebook/raw/master/doc/register_application.png&quot; alt=&quot;Setting your FB Connect URL&quot; title=&quot;Setting your FB Connect URL&quot; /&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;2. Setting up your Project&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;For Facebook integration you need to place these three files into your project folder:&amp;lt;/p&amp;gt;
&amp;lt;ol&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://github.com/dominiek/node-facebook/raw/master/lib/facebook.js&quot;&amp;gt;facebook.js&amp;lt;/a&amp;gt; - plugin for the Express framework - to be placed in /lib&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://github.com/dominiek/node-facebook/raw/master/lib/jquery.facebook.js&quot;&amp;gt;jquery.facebook.js&amp;lt;/a&amp;gt; - a simple jQuery plugin to interface with the &amp;lt;a href=&quot;http://wiki.developers.facebook.com/index.php/JavaScript_Client_Library&quot;&amp;gt;Facebook JS library&amp;lt;/a&amp;gt; - to be placed in /public/javascripts&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://github.com/dominiek/node-facebook/raw/master/examples/fb_iframe/public/xd_receiver.htm&quot;&amp;gt;xd_receiver.htm&amp;lt;/a&amp;gt; - used by Facebook for opening up a &amp;lt;a href=&quot;http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication_Channel&quot;&amp;gt;Cross-domain Communication Channel&amp;lt;/a&amp;gt; - to be placed in /public&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;p&amp;gt;After adding the dependencies and placing these files, your directory structure should look like this:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;myproject
|-- app.js /* new file */
|-- lib
| |-- support
| | |-- express
| | `-- hashlib
| |-- facebook.js
`-- public
|-- index.html /* new file */
|-- xd_receiver.htm
`-- javascript
`-- jquery.facebook.js
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;To make our application work, we only need to implement two files: index.html and app.js. That's right, we're only using AJAX calls and static files.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;3. In the Browser&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;The provided jQuery plugin provides the following functions that we'll be using:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;fbInit&amp;lt;/strong&amp;gt; - initialize the JS lib and set up the cross-communication channel&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;fbConnect&amp;lt;/strong&amp;gt; - invoke the connect procedure and to synchronize sessions and profile information with our backend&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;fbLogout&amp;lt;/strong&amp;gt; - logout from both the Facebook Application and our NodeJS application&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;fbIsAuthenticated&amp;lt;/strong&amp;gt; - check whether a user is logged in or not&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;First we start out with a simple skeleton that loads jQuery and the Facebook JS library. Please note that you need the div named &amp;lt;em&amp;gt;fb-root&amp;lt;/em&amp;gt; right after the body tag for Facebook's lib to work:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;html&amp;amp;gt;
&amp;amp;lt;head&amp;amp;gt;
&amp;amp;lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
&amp;amp;lt;script type=&quot;text/javascript&quot; src=&quot;/javascripts/jquery.facebook.js&quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
&amp;amp;lt;/head&amp;amp;gt;
&amp;amp;lt;body&amp;amp;gt;
&amp;amp;lt;div id=&quot;fb-root&quot;&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;script type=&quot;text/javascript&quot; src=&quot;http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php&quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
&amp;amp;lt;/body&amp;amp;gt;
&amp;amp;lt;/html&amp;amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Now let's implement a basic UI:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;facebook-connect/index.html&quot; class=&quot;code-link&quot;&amp;gt;index.html&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;!DOCTYPE html PUBLIC &amp;amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;amp;quot;
&amp;amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;amp;quot;&amp;amp;gt;
&amp;amp;lt;html xmlns=&amp;amp;quot;http://www.w3.org/1999/xhtml&amp;amp;quot;&amp;amp;gt;
&amp;amp;lt;head&amp;amp;gt;
&amp;amp;lt;script type=&amp;amp;quot;text/javascript&amp;amp;quot; src=&amp;amp;quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
&amp;amp;lt;script type=&amp;amp;quot;text/javascript&amp;amp;quot; src=&amp;amp;quot;/javascripts/jquery.facebook.js&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
&amp;amp;lt;script type=&amp;amp;quot;text/javascript&amp;amp;quot;&amp;amp;gt;
$(document).ready(function () {
$.fbInit('FACEBOOK_API_KEY');
// FB Connect action
$('#fb-connect').bind('click', function () {
$.fbConnect({'include': ['first_name', 'last_name', 'name', 'pic']}, function (fbSession) {
$('.not_authenticated').hide();
$('.authenticated').show();
$('#fb-first_name').html(fbSession.first_name);
});
return false;
});
// FB Logout action
$('#fb-logout').bind('click', function () {
$.fbLogout(function () {
$('.authenticated').hide();
$('.not_authenticated').show();
});
return false;
});
// Check whether we're logged in and arrange page accordingly
$.fbIsAuthenticated(function (fbSession) {
// Authenticated!
$('.authenticated').show();
$('#fb-first_name').html(fbSession.first_name);
}, function () {
// Not authenticated
$('.not_authenticated').show();
});
});
&amp;amp;lt;/script&amp;amp;gt;
&amp;amp;lt;/head&amp;amp;gt;
&amp;amp;lt;body&amp;amp;gt;
&amp;amp;lt;div id=&amp;amp;quot;fb-root&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;script type=&amp;amp;quot;text/javascript&amp;amp;quot; src=&amp;amp;quot;http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
&amp;amp;lt;div id=&amp;amp;quot;my-account&amp;amp;quot;&amp;amp;gt;
&amp;amp;lt;div class=&amp;amp;quot;authenticated&amp;amp;quot; style=&amp;amp;quot;display: none&amp;amp;quot;&amp;amp;gt;
Hi there &amp;amp;lt;span id=&amp;amp;quot;fb-first_name&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt;!
&amp;amp;lt;a href=&amp;amp;quot;#&amp;amp;quot; id=&amp;amp;quot;fb-logout&amp;amp;quot;&amp;amp;gt;Logout&amp;amp;lt;/a&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;div class=&amp;amp;quot;not_authenticated&amp;amp;quot; style=&amp;amp;quot;display: none&amp;amp;quot;&amp;amp;gt;
&amp;amp;lt;a href=&amp;amp;quot;#&amp;amp;quot; id=&amp;amp;quot;fb-connect&amp;amp;quot;&amp;amp;gt;Connect with Facebook&amp;amp;lt;/a&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;/body&amp;amp;gt;
&amp;amp;lt;/html&amp;amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;h2&amp;gt;4. On the Server&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;The &amp;lt;a href=&quot;http://github.com/visionmedia/express&quot;&amp;gt;Express&amp;lt;/a&amp;gt; plugin is initialized like any other plugin in the environment configuration routine, but takes your Facebook API key and Secret as mandatory initialization arguments:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;use(require('facebook').Facebook, {
apiKey: 'FACEBOOK_API_KEY',
apiSecret: 'FACEBOOK_API_SECRET'
})
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Next we need to implement 3 AJAX actions to make jquery.facebook.js work:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;GET /fbSession&amp;lt;/strong&amp;gt; - Is the current user logged in? Or is there a cookie/param present I can use to authenticate?&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;POST /fbSession&amp;lt;/strong&amp;gt; - Update additional information about the user (name, picture, etc)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;POST /fbLogout&amp;lt;/strong&amp;gt; - Called after logout from the Facebook Application took place&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;Here is an example Express application that uses no persistent storage:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;facebook-connect/app.js&quot; class=&quot;code-link&quot;&amp;gt;app.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require.paths.unshift(__dirname + '/../../lib')
require.paths.unshift(__dirname + '/../../lib/support/express/lib')
require.paths.unshift(__dirname + '/../../lib/support/hashlib/build/default')
require('express')
require('express/plugins')
configure(function(){
use(MethodOverride)
use(ContentLength)
use(Cookie)
use(Session)
use(Logger)
use(require('facebook').Facebook, {
apiKey: 'FACEBOOK_API_KEY',
apiSecret: 'FACEBOOK_API_SECRET'
})
set('root', __dirname)
})
// Called to get information about the current authenticated user
get('/fbSession', function(){
var fbSession = this.fbSession()
if(fbSession) {
// Here would be a nice place to lookup userId in the database
// and supply some additional information for the client to use
}
// The client will only assume authentication was OK if userId exists
this.contentType('json')
this.halt(200, JSON.stringify(fbSession || {}))
})
// Called after a successful FB Connect
post('/fbSession', function() {
var fbSession = this.fbSession() // Will return null if verification was unsuccesful
if(fbSession) {
// Now that we have a Facebook Session, we might want to store this new user in the db
// Also, in this.params there is additional information about the user (name, pic, first_name, etc)
// Note of warning: unlike the data in fbSession, this additional information has not been verified
fbSession.first_name = this.params.post['first_name']
}
this.contentType('json')
this.halt(200, JSON.stringify(fbSession || {}))
})
// Called on Facebook logout
post('/fbLogout', function() {
this.fbLogout();
this.halt(200, JSON.stringify({}))
})
// Static files in ./public
get('/', function(file){ this.sendfile(__dirname + '/public/index.html') })
get('/xd_receiver.htm', function(file){ this.sendfile(__dirname + '/public/xd_receiver.htm') })
get('/javascripts/jquery.facebook.js', function(file){ this.sendfile(__dirname + '/public/javascripts/jquery.facebook.js') })
run()
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;The verification of Facebook data by the server-side is done by using the Application Secret and the signature that's sent along with the data. First, all parameters and cookies are put together in one string and then the Application Secret is appended to it. The MD5 hash of this string should match the signature that's included. &amp;lt;a href=&quot;http://wiki.developers.facebook.com/index.php/Verifying_The_Signature&quot;&amp;gt;more about verifying the signature&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&amp;lt;p&amp;gt;In any subsequently added action, you can access the Facebook Session simply like this:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;get('/hello', function () {
var fbSession = this.fbSession()
return 'Hello ' + ' user ' + fbSession.userId + '!';
})
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h2&amp;gt;6. Further Development&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;In this article we went into the direction of putting a lot of UI flow and controller logic into the browser. This can be quite counter-intuitive. As a Rails-programmer and former RJS lover, I can attest to that. However, while there are still remaining issues like SEO and accessibility, this approach allows the server to really focus on data modelling/routing and has numerous scaling benefits.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;All examples in this article and more can be found on the &amp;lt;a href=&quot;http://github.com/dominiek/node-facebook&quot;&amp;gt;node-facebook repository&amp;lt;/a&amp;gt; I created. If you run into any obstacles, feel free to &amp;lt;a href=&quot;http://dominiek.com/&quot;&amp;gt;contact me&amp;lt;/a&amp;gt; or fork the code. I hope to soon write a similar plugin for Twitter's OAUTH based login.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Appendix A: Facebook Troubleshooting Checklist&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Debugging Facebook Application problems can be a real pain in the neck, here is a simple checklist distilled from many frustrating mind-cycles:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;Are you sure xd_receiver.htm is in place and being accessed?&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Are you sure the &amp;lt;div id=&quot;root&quot;&amp;gt;&amp;lt;/div&amp;gt; element is present in the body?&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;If you are using Safari with iFrames, there are some &amp;lt;a href=&quot;http://saizai.livejournal.com/897522.html&quot;&amp;gt;cookie hacks&amp;lt;/a&amp;gt; you need to do&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Are cookies being set successfully after FB connect?&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Are you sure you're using the correct API keys?&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;</description>
<pubDate>Thu Mar 18 2010 22:00:00 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>What is &quot;this&quot;?</title>
<category></category>
<author>tim@creationix.com (Tim Caswell)</author>
<guid>http://howtonode.org/what-is-this</guid>
<link/>http://howtonode.org/what-is-this
<description>&amp;lt;p&amp;gt;Most people that learn JavaScript are coming from a background in another language. This brings with it a view of how the world works that may be different from how it really works in JavaScript. For this and other reasons, JavaScript is often misunderstood. It's not entirely our fault, the language was designed to work like one thing (scheme-like), but look like another (c-like). This article will describe lexical scope and the &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; variable and how to control them rather than be controlled by them when in coding JavaScript.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;It's all about where you are.&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;In all programming languages, there is this idea of current scope and current context. In JavaScript we have a lexical scope and a current &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; context.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;In JavaScript all new scopes are created through &quot;&amp;lt;code&amp;gt;function&amp;lt;/code&amp;gt;&quot; definitions. But contrary to other c-like languages, this is the &amp;lt;em&amp;gt;only&amp;lt;/em&amp;gt; way to make a new scope. For loops don't do it, if blocks don't do it, plain curly braces assuredly don't do it. This simplicity is both a blessing and a curse. First let's have a couple of examples to explain creating scopes.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;This is an example of global scope:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/global.js&quot; class=&quot;code-link&quot;&amp;gt;global.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Define a couple of global variables
var name = &amp;amp;quot;Tim&amp;amp;quot;;
var age = 28;
// Access one of them from the global scope
name;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 'Tim'&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;This is an example of local scope:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/local.js&quot; class=&quot;code-link&quot;&amp;gt;local.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Create a couple of local variables in a function.
function newScope() {
var name = &amp;amp;quot;tim&amp;amp;quot;;
var age = 28;
}
// Try to access the local variables from the global scope
// This will cause an error.
name;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;error&quot;&amp;gt;&amp;lt;dt&amp;gt;Error&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;ReferenceError: name is not defined&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;h3&amp;gt;Lexical Scope&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Lexical scope is the key to making closures work. Here's a quote from wikipedia about closures and lexical scope:&amp;lt;/p&amp;gt;
&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;In computer science, a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be &quot;closed over&quot; its free variables. A closure is defined within the scope of its free variables, and the extent of those variables is at least as long as the lifetime of the closure itself.&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&amp;lt;p&amp;gt;So what does all that mean? Here's an example:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/lexical.js&quot; class=&quot;code-link&quot;&amp;gt;lexical.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var sys = require('sys');
var name = &amp;amp;quot;outer&amp;amp;quot;;
function one() {
var name = &amp;amp;quot;middle&amp;amp;quot;;
var other = &amp;amp;quot;findme&amp;amp;quot;;
function two() {
var name = &amp;amp;quot;inner&amp;amp;quot;;
// Here `name` is &amp;amp;quot;inner&amp;amp;quot; and `other` is &amp;amp;quot;findme&amp;amp;quot;
sys.p({name: name, other: other});
}
two();
// Here `name` is &amp;amp;quot;middle&amp;amp;quot; and `other` is &amp;amp;quot;findme&amp;amp;quot;
sys.p({name: name, other: other});
}
one();
// Here `name` is &amp;amp;quot;outer&amp;amp;quot; and `other` is undefined.
sys.p({name: name});
sys.p({other: other});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;{ name: 'inner', other: 'findme' }
{ name: 'middle', other: 'findme' }
{ name: 'outer' }
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;dl class=&quot;error&quot;&amp;gt;&amp;lt;dt&amp;gt;Error&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;ReferenceError: other is not defined&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Here we see that local variables in an inner scope can shadow variables by the same name in the outer scope. But from the outside, variables in the inside don't exist. Lexical scope is 100% based on the physical location of the variables in the nesting in the code. It doesn't matter what path you might take to get to the inner function. That's how closures are able to make inner variables usable.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/closure.js&quot; class=&quot;code-link&quot;&amp;gt;closure.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var sys = require('sys');
// Make a function that returns a closure function.
function myModule() {
var name = &amp;amp;quot;tim&amp;amp;quot;, age = 28;
return function greet() {
return &amp;amp;quot;Hello &amp;amp;quot; + name + &amp;amp;quot;. Wow, you are &amp;amp;quot; + age + &amp;amp;quot; years old.&amp;amp;quot;;
}
}
// call `myModule` to get a closure out of it.
var greeter = myModule();
// Call the closure
greeter();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 'Hello tim. Wow, you are 28 years old.'&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The variables &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;age&amp;lt;/code&amp;gt; are local to the &amp;lt;code&amp;gt;myModule&amp;lt;/code&amp;gt; function, but when we call &amp;lt;code&amp;gt;greeter&amp;lt;/code&amp;gt; from the global scope, it doesn't throw an error. This is because the &amp;lt;code&amp;gt;greet&amp;lt;/code&amp;gt; function has &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;age&amp;lt;/code&amp;gt; in it's lexical scope and so they're accessible as if they were local variables. Basically the way variable lookup works is that it goes up scope by scope looking for a variable by the requested name.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;The context of &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot;&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;In addition to the lexical scope. JavaScript adds another layer of locality through the special keyword &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot;. This keyword looks and acts like any other javascript variable except that you can't modify it. It acts as a reference to the context object, and as an object, you can get to it's properties through normal dot or bracket notation. The magic is that the value of &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; changes depending on what context your executing in. In most cases, the context is the receiver of the message. For example:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/this.js&quot; class=&quot;code-link&quot;&amp;gt;this.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#person&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var Person = {
name: &amp;amp;quot;Tim&amp;amp;quot;,
age: 28,
greeting: function () {
return &amp;amp;quot;Hello &amp;amp;quot; + this.name + &amp;amp;quot;. Wow, you are &amp;amp;quot; + this.age + &amp;amp;quot; years old.&amp;amp;quot;;
}
};
Person.greeting();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 'Hello Tim. Wow, you are 28 years old.'&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Note that I was able to access &amp;lt;code&amp;gt;Person.name&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Person.age&amp;lt;/code&amp;gt; from within &amp;lt;code&amp;gt;Person.greeting&amp;lt;/code&amp;gt;. &amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;&quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; is where it bites&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;The previous code almost looks like objects from other languages. But that's where it bites you. As the author of the &amp;lt;code&amp;gt;Person&amp;lt;/code&amp;gt; module, you have no assurance that &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; will be the same as &quot;&amp;lt;code&amp;gt;Person&amp;lt;/code&amp;gt;&quot;. For example, what if I wanted to store the greeting function somewhere else:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/this.js&quot; class=&quot;code-link&quot;&amp;gt;this.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#standalone&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var greeting = Person.greeting;
greeting(); // Will get undefined for `this.name` and `this.age`
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 'Hello undefined. Wow, you are undefined years old.'&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The problem here is that &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; in the body of the greeting function is now the global object and not the &amp;lt;code&amp;gt;Person&amp;lt;/code&amp;gt; object. How about one more example just for fun:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/this.js&quot; class=&quot;code-link&quot;&amp;gt;this.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#dog&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var Dog = {
name: &amp;amp;quot;Alfred&amp;amp;quot;,
age: 110,
greeting: Person.greeting
}
Dog.greeting(); // This will work and it will show the dog's data.
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 'Hello Alfred. Wow, you are 110 years old.'&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The greeting function in Dog and the function in Person are &amp;lt;strong&amp;gt;the same&amp;lt;/strong&amp;gt; function. They're both references to the same object in memory. But depending on where it's called from, can change the value of &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot;. Basically &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; is whatever object comes before the dot in the call. That's why &amp;lt;code&amp;gt;Dog.greeting()&amp;lt;/code&amp;gt; uses &amp;lt;code&amp;gt;Dog&amp;lt;/code&amp;gt; as &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; and &amp;lt;code&amp;gt;Person.greeting()&amp;lt;/code&amp;gt; uses &amp;lt;code&amp;gt;Person&amp;lt;/code&amp;gt;. When there is nothing before the function call, then the global object is used for &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot;.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Taming &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot;&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;JavaScript comes with a couple of handy-dandy functions on &amp;lt;code&amp;gt;Function.prototype&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;call&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;apply&amp;lt;/code&amp;gt;. They work about the same, but take arguments differently. Going on from the previous examples, let's make a new object that doesn't even have a &amp;lt;code&amp;gt;greeting&amp;lt;/code&amp;gt; function, but can still be used by it.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/this.js&quot; class=&quot;code-link&quot;&amp;gt;this.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#alien&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var Alien = {
name: &amp;amp;quot;Zygoff&amp;amp;quot;,
age: 5432
}
Person.greeting.call(Alien);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 'Hello Zygoff. Wow, you are 5432 years old.'&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;What we're saying here is to call the Person.greeting function, but inject the object &amp;lt;code&amp;gt;Alien&amp;lt;/code&amp;gt; as the &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; value. We could have used &amp;lt;code&amp;gt;apply&amp;lt;/code&amp;gt; just the same for this example since there are no extra arguments.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Let's make a generic function that can work with any object that has &amp;lt;code&amp;gt;age&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; properties:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/this.js&quot; class=&quot;code-link&quot;&amp;gt;this.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#make-older&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;function makeOlder(years, newname) {
this.age += years;
if (newname) {
this.name = newname;
}
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;This function just adds years to any &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; object and optionally replaces the name. It's not tied to any particular object. (In fact any function not using variables from outer scopes is independent) Here is how we would use it with either &amp;lt;code&amp;gt;call&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;apply&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/this.js&quot; class=&quot;code-link&quot;&amp;gt;this.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#use-it&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;makeOlder.call(Person, 2, &amp;amp;quot;Old Tim&amp;amp;quot;);
makeOlder.apply(Dog, [1, &amp;amp;quot;Shaggy&amp;amp;quot;]);
sys.p({Person: Person, Dog: Dog});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;{ Person: { name: 'Old Tim', age: 30, greeting: [Function] }
, Dog: { name: 'Shaggy', age: 111, greeting: [Function] }
}
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The difference is that each extra argument to &amp;lt;code&amp;gt;call&amp;lt;/code&amp;gt; is an argument passed to the function. But with apply, there are only two arguments. They are the &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; object and an array of the parameters to pass to the function.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Binding &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot;&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Sometimes we really like our nice OOP style code and want to force JS to act that way. We don't like &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; changing on us depending on how we're calling it all the time. The most common place where it bites me is in an event based system that takes callbacks as arguments. Here is a simple example from jQuery.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/jquery.js&quot; class=&quot;code-link&quot;&amp;gt;jquery.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#cart&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;Cart = {
items: [1,4,2],
onClick: function () {
// Do something with this.items.
}
}
$(&amp;amp;quot;#mybutton&amp;amp;quot;).click(Cart.onClick);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;While this looks ok, it's waiting for disaster. Even though we have &amp;lt;code&amp;gt;Cart.onClick&amp;lt;/code&amp;gt;, we're not calling the &amp;lt;code&amp;gt;onClick&amp;lt;/code&amp;gt; function yet. the jQuery code will accept is as some parameter and at that point it has no way of knowing that &amp;lt;code&amp;gt;onClick&amp;lt;/code&amp;gt; came from the &amp;lt;code&amp;gt;Cart&amp;lt;/code&amp;gt; object. Your &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; won't be what you expect when it finally gets called.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Let's combine our knowledge of closures and lexical scope and make &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; scope act like it does in most OOP languages.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/jquery.js&quot; class=&quot;code-link&quot;&amp;gt;jquery.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#bad&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;$(&amp;amp;quot;#mybutton&amp;amp;quot;).click(function () { Cart.onClick() });
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;We created a little closure that then calls &amp;lt;code&amp;gt;Cart.onClick()&amp;lt;/code&amp;gt;. The problem with this (besides being long and ugly) is that is doesn't pass through any function parameters or return values. We can fix that some.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/jquery.js&quot; class=&quot;code-link&quot;&amp;gt;jquery.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#better&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;$(&amp;amp;quot;#mybutton&amp;amp;quot;).click(function () { return Cart.onClick.apply(Cart, arguments) });
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;This works, but it's even harder to read and understand. If you don't already know, &quot;&amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt;&quot; is another special keyword that is an array-like object that contains the arguments that were passed to the current inner-most function.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;If Cart was a globally accessible singleton object we could just use the variable &amp;lt;code&amp;gt;Cart&amp;lt;/code&amp;gt; directly instead of relying on &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot;, but that's often not the case when you have &quot;classes&quot; of objects sharing common functionality.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Wouldn't it be easier to somehow modify &amp;lt;code&amp;gt;Cart.onClick&amp;lt;/code&amp;gt; so that &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; was always Cart from within it?&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/jquery.js&quot; class=&quot;code-link&quot;&amp;gt;jquery.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#bind&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;function bind(fn, scope) {
return function () {
return fn.apply(scope, arguments);
}
}
Cart.onClick = bind(Cart.onClick, Cart);
$(&amp;amp;quot;#mybutton&amp;amp;quot;).click(Cart.onClick);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;There are various ways of doing this and in fact it's often not the right solution. If you're just trying to make JavaScript act like language X then this is a great little tool, but it's better to just learn the semantics of JavaScript.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Here we've just created a closure that has the scope embedded. Then we replace Cart.onClick with the bound closure and use the apply magic to pass through any arguments and return value automatically.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Var statements&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;The var statement is really just a keyword to specify which nested scope a variable applies to. In fact, if you never used &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt;, then all your variables would be global and walk all over each other.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/var.js&quot; class=&quot;code-link&quot;&amp;gt;var.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#globals&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;global_var = true;
function someFunc() {
another_global = 42;
var local_var = 5;
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; true&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;This is especially dangerous in things like for loops:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/var.js&quot; class=&quot;code-link&quot;&amp;gt;var.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#loops&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;function sum(start, end) {
var n = 0;
for (i = start; i &amp;amp;lt;= end; i++) {
n += i;
}
return n;
}
function nested_sum(num) {
var n = 0;
for (i = 1; i &amp;amp;lt;= num; i++) {
n += sum(1, i);
}
return n;
}
nested_sum(3); // Expected value is 10, but i values get tangled
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 7&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; variable in both loops is the &amp;lt;strong&amp;gt;same&amp;lt;/strong&amp;gt; variable and so the inner loop will break the outer loop and give the wrong answer. Also if I had not put var statements before the two &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; variables, then they would walk over each other and give a wrong answer too.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;There is one word of caution for &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; users. It doesn't matter where in the function body you put the &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; word. It only matters which function body you put it in. And it's scope is inner to function parameters. For example:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;what-is-this/var.js&quot; class=&quot;code-link&quot;&amp;gt;var.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#onevar&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;name = &amp;amp;quot;Tim&amp;amp;quot;;
function greet() {
sys.p(name);
// name is undefined
// Lots of code, and them later on you have:
var name;
}
greet();
function greet2(name) {
sys.p(name);
// name is &amp;amp;quot;Tim&amp;amp;quot; because functions arguments are special.
// Lots of code, and them later on you have:
var name;
}
greet2(&amp;amp;quot;Tim&amp;amp;quot;);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;undefined
'Tim'
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;This is why &amp;lt;a href=&quot;http://www.jslint.com/&quot;&amp;gt;jslint&amp;lt;/a&amp;gt; tells you to put all your var statements at the top of a function. I've actually had this one bite me because there was a page of code between the top of the function and the &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; statement. I couldn't figure out why my variable I was passing in got set to &amp;lt;code&amp;gt;undefined&amp;lt;/code&amp;gt; before the first line of the function body.&amp;lt;/p&amp;gt;
&amp;lt;hr /&amp;gt;
&amp;lt;h2&amp;gt;Conclusion&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;There some universal rules that will go a long way to understanding scope in JavaScript:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;The only way to create a new scope is through the &amp;lt;code&amp;gt;function&amp;lt;/code&amp;gt; keyword. Nothing else, not even &amp;lt;code&amp;gt;for ... in&amp;lt;/code&amp;gt; blocks create new scopes.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;The &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; statement declares a variable as local to the current scope and the &amp;lt;strong&amp;gt;entire&amp;lt;/strong&amp;gt; current scope, not just from the &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt; statement onward. These local variables shadow any existing variables from outer scopes.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;All variables except &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; and &quot;&amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt;&quot; follow lexical scope. Their meaning is defined by the &amp;lt;strong&amp;gt;physical location&amp;lt;/strong&amp;gt; in the code.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;The variables &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; and &quot;&amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt;&quot; change at &amp;lt;strong&amp;gt;every&amp;lt;/strong&amp;gt; nesting level. If you want to preserve them in a closure, then you need to first create a reference to their value through another variable that follows lexical scope.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;The value of &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; is defined by &amp;lt;strong&amp;gt;how&amp;lt;/strong&amp;gt; the function is called. You can control this through use of &amp;lt;code&amp;gt;apply&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;call&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;There are exceptions to these rules, but only when messing with things like function decompilation, &amp;lt;code&amp;gt;eval&amp;lt;/code&amp;gt;, and the &amp;lt;code&amp;gt;with&amp;lt;/code&amp;gt; keyword. Even then you're still following the rules, just not in the way you'd expect. Function decompilation + &amp;lt;code&amp;gt;eval&amp;lt;/code&amp;gt; transplants a function into a new lexical scope. And &amp;lt;code&amp;gt;with&amp;lt;/code&amp;gt; can be used to make things like &amp;lt;code&amp;gt;this.name&amp;lt;/code&amp;gt; appear as local lexical variables but work like &quot;&amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt;&quot; properties.&amp;lt;/p&amp;gt;</description>
<pubDate>Mon Mar 08 2010 18:59:10 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>JavaScript Meetup Hamburg + Slides</title>
<category></category>
<author>felix@debuggable.com</author>
<guid>http://www.debuggable.com/posts/javascript-meetup-hamburg-slides:4b8f9986-4e64-4755-b420-074dcbdd56cb</guid>
<link/>http://feedproxy.google.com/~r/debuggable/~3/nkohVEbm3a0/javascript-meetup-hamburg-slides:4b8f9986-4e64-4755-b420-074dcbdd56cb
<description>&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Update:&amp;lt;/strong&amp;gt; Andy Wenk posted &amp;lt;a href=&quot;http://blog.netzmeister-st-pauli.com/post/426345602/hhjs-first-meetup-hamburg&quot;&amp;gt;a very nice summary&amp;lt;/a&amp;gt; of the event.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Last night Tim and I took a little road trip to Hamburg. I had no idea the &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Reeperbahn&quot;&amp;gt;Reeperbahn&amp;lt;/a&amp;gt; looked like Las Vegas : ).&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Anyway, our actual destination was the first &amp;lt;a href=&quot;http://twitter.com/hhjs&quot;&amp;gt;Hamburg JS&amp;lt;/a&amp;gt; meetup where &amp;lt;a href=&quot;http://www.nonblocking.io/&quot;&amp;gt;Malte Ubl&amp;lt;/a&amp;gt; invited me to speak about node.js. The turnout was fantastic, and thanks to &amp;lt;a href=&quot;http://www.sinnerschrader.de/&quot;&amp;gt;SinnerSchrader&amp;lt;/a&amp;gt;'s hosting of the event, there was plenty of pizza, beer and an absolutely fantastic location.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;I've also updated my previous node.js talk, all the examples should now be 0.1.30+ compatible, and the section about &quot;The Future&quot; of node has a more recent and interesting list of things that are on the radar:&amp;lt;/p&amp;gt;
&amp;lt;div style=&quot;width:425px&quot; id=&quot;__ss_3332942&quot;&amp;gt;&amp;lt;strong style=&quot;display:block;margin:12px 0 4px&quot;&amp;gt;&amp;lt;a href=&quot;http://www.slideshare.net/the_undefined/nodejs-a-quick-tour-ii&quot; title=&quot;Node.js - A Quick Tour II&quot;&amp;gt;Node.js - A Quick Tour II&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;object width=&quot;425&quot; height=&quot;355&quot;&amp;gt;&amp;lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=node-100304052653-phpapp02&amp;amp;stripped_title=nodejs-a-quick-tour-ii&quot; /&amp;gt;&amp;lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;/&amp;gt;&amp;lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot;/&amp;gt;&amp;lt;embed src=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=node-100304052653-phpapp02&amp;amp;stripped_title=nodejs-a-quick-tour-ii&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;355&quot;&amp;gt;&amp;lt;/embed&amp;gt;&amp;lt;/object&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;You can also &amp;lt;a href=&quot;http://felixge.s3.amazonaws.com/10/nodejs-a-quick-tour-2.pdf&quot;&amp;gt;download the slides as PDF&amp;lt;/a&amp;gt; (164 kb).&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;--fg&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;img style=&quot;display: none;&quot; src=&quot;http://www.debuggable.com/posts/tick/4b8f9986-4e64-4755-b420-074dcbdd56cb&quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;img src=&quot;http://feeds.feedburner.com/~r/debuggable/~4/nkohVEbm3a0&quot; height=&quot;1&quot; width=&quot;1&quot;/&amp;gt;</description>
<pubDate>Thu Mar 04 2010 11:43:53 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Tasks and Prompts -- Implementing Simple Work Queues</title>
<category></category>
<author>rsdoiel@gmail.com (R. S. Doiel)</author>
<guid>http://howtonode.org/tasks-and-prompts</guid>
<link/>http://howtonode.org/tasks-and-prompts
<description>&amp;lt;p&amp;gt;Sometimes all you really need is orderly execution not blocking I/O to get the job done. Tasks and prompts is a light weight implementation of the work queue design pattern.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Implementing Simple Work Queues&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;The other day I was converting a couple Bash installer scripts to node scripts. I recognized a familiar design pattern -- the work queue. Here's the requirements for a typical work queue approach -&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;tasks are queued, first in first out (i.e. tracked)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;tasks once started continue without further intervention&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;tasks are independent (i.e. task A does not depend on task B or visa versa)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;tasks are execute once&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;h2&amp;gt;My requirements&amp;lt;/h2&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;tasks fired in sequence without concern for when they complete&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;some tasks required a prompt and response before firing&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;I wanted to queue tasks and prompts before running the work queue&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;A simple JavaScript array works fine as a first in first out queue (i.e. shift() pops the zeroth position off). An object's properties can keep track of what text I wanted to displayed; the callback to be fired; and if I need to show a prompt or get a response when firing a callback. tasks-and-prompts.js is a simple example of doing that:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;tasks-and-prompts/tasks-and-prompts.js&quot; class=&quot;code-link&quot;&amp;gt;tasks-and-prompts.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var sys = require('sys'), /* We need the sys module */
work_queue = []; /* This holds our first in, first out queue of prompts and tasks */
/* This is the method we used to put prompted items into the work queue.
prompts will pass a response to the callback method. */
prompt = function (msg, callback) {
/* A queued item has some text, a callback and a work queue type (i.e. work_type) */
work_queue.push({'text' : msg, 'callback' : callback, 'work_type' : 'prompt'})
};
/* task puts items into the work queue that don't require a prompt and response.
tasks don't wait for an answer, they just get fired. Since no response is
pending the callback will get called without any parameters. */
task = function (label, callback) {
work_queue.push({'text' : label, 'callback' : callback, 'work_type' : 'task' });
};
/* This is our work horse function. It runs all the tasks and prompts */
run = function() {
/* this is just a convenience inner function to make the code easier to read.
it fires off tasks until it finds a prompt or nothing is left in the
work queue. */
taskRunner = function () {
var action; /* Place holder for action we shift out of the queue */
while (work_queue.length &amp;amp;gt; 0) {
/* If next queued item is a prompt, show the prompt and exit taskRunner. */
if (work_queue[0].work_type === 'prompt') {
sys.puts(work_queue[0].text);
return;
}
/* If we have a task we show the text associated with the task and
fire off the callback. Notice we don't wait for it to return.
Work queue only insures the order of firing not anything else. */
if (work_queue[0].work_type === 'task') {
action = work_queue.shift();
sys.puts(action.text);
action.callback();
}
}
};
/* Process any tasks in the work queue that might be ahead of prompts */
taskRunner();
/* We only open stdio and add a listener if we have items which prompt. */
if (work_queue.length &amp;amp;gt; 0) {
(function () {
/* Open the standard input stream and set the encoding to UTF-8 */
var stdin = process.openStdin();
stdin.setEncoding('utf8');
/* This is the callback for handing data events from standard input. */
inputHandler = function (response) {
/* Now that we're listening we either handle a prompt or handle a task
until the work queue is empty. */
while (work_queue.length &amp;amp;gt; 0) {
if (work_queue[0].work_type === 'prompt') {
action = work_queue.shift();
action.callback(response);
}
/* If any tasks, prompts run next */
taskRunner();
}
if (work_queue.length === 0) {
stdin.end();
}
};
/* This is the callback for doing all the cleanup. */
cleanupHandlers = function () {
stdin.removeListener('data', inputHandler);
stdin.removeListener('end', cleanupHandlers);
};
/* Now that we have defined out handlers, add them as listners for data and end events. */
stdin.addListener('data', inputHandler);
stdin.addListener('end', cleanupHandlers);
}());
}
};
/*
* Now let's setup some tasks and prompts to do some work
*/
/* You might prompt to do some setup before firing your tasks */
prompt(&amp;amp;quot;Are you there? &amp;amp;quot;, function (data) {
sys.puts(&amp;amp;quot;Answer was: &amp;amp;quot; + data);
});
/* Tasks run unattended. work_queue only ensures the order
the callbacks are fired not order of completion */
task('Count to three:', function () {
for (i = 1; i &amp;amp;lt;= 3; i += 1) {
sys.puts(&amp;amp;quot;count: &amp;amp;quot; + i);
}
});
/* Since run might open/close stdio it needs to be the last thing called. */
run();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;h2&amp;gt;Explanations&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;In this simple example I prompt the user to answer a question then count to three. Pretty trivial but it's an implantation of a the work queue pattern. That pattern is common in installation or management scripts. The only problem with the example above is that it isn't setup as a node module ... wait I did that already! See &amp;lt;a href=&quot;http://github.com/rsdoiel/nshtools&quot;&amp;gt;github.com/rsdoiel/nshtools&amp;lt;/a&amp;gt;. nshtools.js has a more elaborate implementation and includes some other features like command line option processing, mixins of sys, path and fs modules, and high level file commands like cp and mv. The github wiki and the README.md file for nshtools have some more short examples for your enjoyment.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Have fun!&amp;lt;/p&amp;gt;</description>
<pubDate>Sun Feb 28 2010 00:50:22 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Node + Redis = Fun</title>
<category></category>
<author>nsm.nikhil@gmail.com (Nikhil Marathe)</author>
<guid>http://howtonode.org/node-redis-fun</guid>
<link/>http://howtonode.org/node-redis-fun
<description>&amp;lt;p&amp;gt;node brings asynchronous, evented I/O to the server. Redis gives you a blazing fast database with support for strings, lists and sets. Both Redis and Node.js follow certain patterns, Redis for data-storage, and node for event based programming. I hope to give an introduction to both in this article. By the time we are done, we will have built a &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Pastebin&quot;&amp;gt;Pastebin&amp;lt;/a&amp;gt; service.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Getting Started&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;I will assume that the reader is comfortable with Javascript, including using events and passing around functions.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Before we get down to the code, here is the software you will need:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://nodejs.org/&quot;&amp;gt;node&amp;lt;/a&amp;gt; ( we will use &amp;lt;a href=&quot;http://github.com/ry/node/downloads&quot;&amp;gt;v0.1.91&amp;lt;/a&amp;gt; )&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://code.google.com/p/redis/&quot;&amp;gt;Redis&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://github.com/fictorial/redis-node-client/&quot;&amp;gt;redis-node-client&amp;lt;/a&amp;gt; - to connect to Redis from node. Already bundled within snip.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://github.com/gjritter/nerve/&quot;&amp;gt;nerve&amp;lt;/a&amp;gt; - A micro-framework to handle routing. Use the bundled version which works with node v0.1.91.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://documentcloud.github.com/underscore/&quot;&amp;gt;underscore.js&amp;lt;/a&amp;gt; - A collection of useful javascript functions, we will use only one.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&quot;http://pygments.org/&quot;&amp;gt;Pygments&amp;lt;/a&amp;gt; - Python program to syntax highlight code.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;Finally, here is how our code is organized.&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;snip
|- deps/
|- redis-node-client/
|- nerve/
|- underscore.js
|- run
|- snip.js
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h2&amp;gt;A note on the node module system&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Node modules are used by importing them into the current scope using &amp;lt;code&amp;gt;require()&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;NODE_PATH&amp;lt;/code&amp;gt; environment variable is used to search for modules. When you have lots of dependencies, it gets boring to keep entering the full paths in the requires all the time. So rather than directly invoking&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;node &amp;amp;lt;script&amp;amp;gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;to test our application, we will be using this shell script, so that we can directly do&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;require( 'nerve' )
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;and have it work &amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;#!/usr/bin/env sh
export SNIP_PATH=$(dirname `readlink -f $0`)
export NODE_PATH=\
$NODE_PATH\
:$SNIP_PATH\
:$SNIP_PATH/deps/redis-node-client/lib\
:$SNIP_PATH/deps/nerve/lib\
:$SNIP_PATH/deps/ #underscore.js
node &quot;$@&quot;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h2&amp;gt;The Big Picture&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Here is how our application works&amp;lt;/p&amp;gt;
&amp;lt;ol&amp;gt;
&amp;lt;li&amp;gt;You visit the http://localhost:8000/&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Post your code snippet, and choose the language&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Get a unique url http://localhost:8000/&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;h2&amp;gt;Database Schema&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;See the &amp;lt;a href=&quot;http://code.google.com/p/redis/wiki/CommandReference&quot;&amp;gt;full list of Redis commands&amp;lt;/a&amp;gt;. redis-node-client will abstract the actual communication.&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;So how do we represent our data ( snippets ) so that we can do all the things we want to do?&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Relational databases have rows and columns, where columns identify various parts of the data. But key-value stores, including Redis, don't have that. The solution is to encode the column in the key itself. So for each snippet we will have a key snippet:&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;. So how do we prevent two snippets from having the same &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt;? In MySQL you would probably set the &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; column of the &amp;lt;code&amp;gt;snippets&amp;lt;/code&amp;gt; table to &amp;lt;code&amp;gt;PRIMARY KEY AUTO_INCREMENT&amp;lt;/code&amp;gt;. We will similarly use a key &amp;lt;em&amp;gt;nextid&amp;lt;/em&amp;gt; which is a simple integer, to keep track of snippets. We will use Redis's &amp;lt;em&amp;gt;atomic&amp;lt;/em&amp;gt; operation &amp;lt;code&amp;gt;INCR&amp;lt;/code&amp;gt; to get an id:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;INCR nextid
Now you can use the new returned id, which will be unique
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;The snippet itself is stored as a JSON map. The inbuilt functions &amp;lt;code&amp;gt;JSON.stringify&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;JSON.parse&amp;lt;/code&amp;gt; are used to convert to and fro.&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;{
'language' : '&amp;amp;lt;language&amp;amp;gt;',
'snippet' : '&amp;amp;lt;Actual data&amp;amp;gt;',
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Redis allows values to be upto 1GB in size, so we don't have to worry about that.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;First code&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;First lets get nerve started so that we get something which works. nerve accepts a list of routes, based or regular expressions, and calls the associated function. For the first run lets just display the string 'Hello World'. Add the following to snip.js:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;nerve.create( [
[ /.*/, function( req, res ) { res.respond( &quot;Hello World&quot; ); } ]
]).listen( 8000 );
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;./run snip.js&amp;lt;/code&amp;gt; and point your browser to http://localhost:8000. Its as simple as that. &amp;lt;code&amp;gt;/.*/&amp;lt;/code&amp;gt; means match any URL and invoke this function. Each function is passed two argIts as simple as that. &amp;lt;code&amp;gt;/.*/&amp;lt;/code&amp;gt; means match any URL and invoke this function. Each function is passed two arguments, &amp;lt;code&amp;gt;request&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;response&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;request&amp;lt;/code&amp;gt; will have lots of information about the client request, like headers and form data which we are interested in. &amp;lt;code&amp;gt;response&amp;lt;/code&amp;gt; is used to send content back to the client. &amp;lt;code&amp;gt;respond.respond(data)&amp;lt;/code&amp;gt; sends all the data to the browser and closes the connection.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Node relies on asynchronous I/O and so we will often be dealing with streaming data. The lower level methods &amp;lt;code&amp;gt;respond.sendHeader()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;respond.write()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;response.close()&amp;lt;/code&amp;gt; will allow us to apply streaming. This will be used when we Syntax-highlight code.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Adding Snippets&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Before we can do anything, we need some data, so let's create the form. Since it's pretty simple, we'll just put it as a string. Usually you would store all these &amp;lt;em&amp;gt;views&amp;lt;/em&amp;gt; in files and stream them over the connection.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;A particularly nasty part of our code is the list of languages, generated by &amp;lt;a href=&quot;http://gist.github.com/310877&quot;&amp;gt;getLanguageList&amp;lt;/a&amp;gt;, which I haven't included here, but is present in the code. Ideally you wouldn't have this &amp;lt;em&amp;gt;data&amp;lt;/em&amp;gt; in your &amp;lt;em&amp;gt;code&amp;lt;/em&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;So this is a part of &amp;lt;code&amp;gt;snip.js&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;node-redis-fun/snip.js&quot; class=&quot;code-link&quot;&amp;gt;snip.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#formHtml&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var formHtml = '&amp;amp;lt;form action=&amp;amp;quot;/add&amp;amp;quot; method=&amp;amp;quot;post&amp;amp;quot;&amp;amp;gt;'
+ '&amp;amp;lt;label for=&amp;amp;quot;code&amp;amp;quot;&amp;amp;gt;Paste code&amp;amp;lt;/label&amp;amp;gt;&amp;amp;lt;br&amp;amp;gt;'
+ '&amp;amp;lt;textarea name=&amp;amp;quot;code&amp;amp;quot; rows=&amp;amp;quot;25&amp;amp;quot; cols=&amp;amp;quot;80&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/textarea&amp;amp;gt;&amp;amp;lt;br&amp;amp;gt;'
+ '&amp;amp;lt;label for=&amp;amp;quot;language&amp;amp;quot;&amp;amp;gt;Language&amp;amp;lt;/label&amp;amp;gt;'
+ '&amp;amp;lt;select name=&amp;amp;quot;language&amp;amp;quot;&amp;amp;gt;'
+ genLanguageList()
+ '&amp;amp;lt;/select&amp;amp;gt;'
+ '&amp;amp;lt;input type=&amp;amp;quot;submit&amp;amp;quot; value=&amp;amp;quot;Paste!&amp;amp;quot; /&amp;amp;gt;&amp;amp;lt;/form&amp;amp;gt;';
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var addSnippet = function() {}
var showSnippet = function() {}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;node-redis-fun/snip.js&quot; class=&quot;code-link&quot;&amp;gt;snip.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#create&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;
nerve.create( [
[ /^\/([0-9]+)/, showSnippet ],
[ nerve.post(&amp;amp;quot;/add&amp;amp;quot;), addSnippet ],
[ &amp;amp;quot;/&amp;amp;quot;, function( req, res ) { res.respond( formHtml ); } ]
]).listen( 8000 );&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Handling post data&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Each &amp;lt;code&amp;gt;nerve&amp;lt;/code&amp;gt; handler function receives two arguments, the first is a &amp;lt;a href=&quot;http://nodejs.org/api.html#_http&quot;&amp;gt;http.ServerRequest&amp;lt;/a&amp;gt; object and the second is a &amp;lt;a href=&quot;http://nodejs.org/api.html#_http&quot;&amp;gt;http.ServerResponse&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;POST data is sent in the body of the Request. Since the data is streamed we have to add a listener function to collect all the data into a buffer. The Request will &amp;lt;em&amp;gt;emit&amp;lt;/em&amp;gt; a &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; signal when all data has been received, so we know when to stop. Once we have all the data, we want to parse it and use it. To make this generic we pass &amp;lt;code&amp;gt;getPostParams&amp;lt;/code&amp;gt; a &amp;lt;a href=&quot;http://howtonode.org/control-flow&quot;&amp;gt;callback&amp;lt;/a&amp;gt; function, which it will call with the results of the query.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;We can parse the form data using the querystring module, so that our function becomes:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;node-redis-fun/snip.js&quot; class=&quot;code-link&quot;&amp;gt;snip.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#getPostParams&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var getPostParams = function(req, callback){
var body = '';
req.addListener('data', function(chunk){
body += chunk;
})
.addListener('end', function() {
var obj = qs.parse( body.replace( /\+/g, ' ' ) ) ;
callback( obj );
});
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Now lets just get &amp;lt;code&amp;gt;addSnippet()&amp;lt;/code&amp;gt; to echo the form data:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var addSnippet = function( req, res ) {
getPostParams(req, function( obj ) {
res.respond( sys.inspect( obj ) );
});
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Now if you try posting some code you should see the object literal being echoed back.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Store the snippet&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Instead of echoing back the POST data, lets now store it in Redis, thus finishing half the implementation of the pastebin. We have to:&amp;lt;/p&amp;gt;
&amp;lt;ol&amp;gt;
&amp;lt;li&amp;gt;Get a unique id for the URL&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Store the data&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;When both succeed, display the URL to the user.&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;p&amp;gt;Again, fitting with node's asynchronous model, we will have to use a sequence of callbacks. Remember that each function introduces a scope with its own &amp;lt;em&amp;gt;this&amp;lt;/em&amp;gt; reference, so make sure you save any this references in outer scopes as some other variable:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;node-redis-fun/snip.js&quot; class=&quot;code-link&quot;&amp;gt;snip.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#addSnippet&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var addSnippet = function( req, res ) {
getPostParams( req, function( obj ) {
var r = redis.createClient();
r.stream.addListener( 'connect', function() {
r.incr( 'nextid' , function( err, id ) {
r.set( 'snippet:'+id, JSON.stringify( obj ), function() {
var msg = 'The snippet has been saved at &amp;amp;lt;a href=&amp;amp;quot;/'+id+'&amp;amp;quot;&amp;amp;gt;'+req.headers.host+'/'+id+'&amp;amp;lt;/a&amp;amp;gt;';
res.respond( msg );
} );
} );
} );
});
};
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The SET operation sets a key to the string value. We use JSON.stringify to get a nice string representation of the request object. Finally once the save is successful we notify the user. That's it, your snippet is saved and ready to show, which brings us to...&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Syntax highlighting&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Since &amp;lt;code&amp;gt;pygmentize&amp;lt;/code&amp;gt; is an external program we are going to spawn a child process and pass it various options. Pygmentize will wait on stdin and write out to stdout. So we are going to do something similar to pipes in shells.&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;pygmentize [options] &amp;amp;lt; redis data &amp;amp;gt; browser
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;It would have been even cooler if redis-node-client supported streaming the data rather than buffering it, but you can't have everything... . Anyway this is how we call pygmentize:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// for now just assume we magically
// got the snippet JSON parsed into obj
// get the language short code
// not that languages is an array of
// [&quot;shortcode&quot;, &quot;name&quot;] elements and filter
// returns a *list* so we need the 0th element.
var shortcode = languages.filter( function(el) {
return el[0] == obj.language;
}) [0][0];
var pyg = cp.spawn( &quot;pygmentize&quot;,
[ &quot;-l&quot;, shortcode,
&quot;-f&quot;, &quot;html&quot;,
&quot;-O&quot;, &quot;full,style=pastie&quot;,
&quot;-P&quot;, &quot;title=Snippet #&quot; + id ] );
pyg.stdout.addListener( &quot;data&quot;, function( coloured ) {
if( coloured )
res.write( coloured );
} );
pyg.addListener( 'exit', function() {
res.end();
});
pyg.stdin.write( obj.code );
pyg.stdin.end();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;The first half is pretty self explanatory. We add a
listener &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; to watch for data on the child's &amp;lt;em&amp;gt;stdout&amp;lt;/em&amp;gt;. Then we send the plain code to pygmentize via its &amp;lt;em&amp;gt;stdin&amp;lt;/em&amp;gt;. It is necessary to close the stream otherwise pygmentize will keep waiting for data and won't generate output. We incrementally write out data as it is received. &amp;lt;code&amp;gt;coloured&amp;lt;/code&amp;gt; will be null when done.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;To get the actual snippet to fetch, we are going to
get nerve to pass us the id. In routing&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;node-redis-fun/snip.js&quot; class=&quot;code-link&quot;&amp;gt;snip.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#create&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;
nerve.create( [
[ /^\/([0-9]+)/, showSnippet ],
[ nerve.post(&amp;amp;quot;/add&amp;amp;quot;), addSnippet ],
[ &amp;amp;quot;/&amp;amp;quot;, function( req, res ) { res.respond( formHtml ); } ]
]).listen( 8000 );
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The &amp;lt;code&amp;gt;([0-9]+)&amp;lt;/code&amp;gt; &amp;lt;em&amp;gt;match group&amp;lt;/em&amp;gt; will be extracted by
nerve and passed to the handler as the third argument.
With that in place we are ready to show the output.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;node-redis-fun/snip.js&quot; class=&quot;code-link&quot;&amp;gt;snip.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#showSnippet&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var showSnippet = function( req, res, id ) {
var r = redis.createClient();
r.stream.addListener( 'connect', function() {
r.get( 'snippet:'+id, function( err, data ) {
if( !data ) {
res.sendHeader( 404 );
res.write( &amp;amp;quot;No such snippet&amp;amp;quot; );
res.end();
return;
}
res.sendHeader( 200, { &amp;amp;quot;Content-Type&amp;amp;quot; : &amp;amp;quot;text/html&amp;amp;quot; } );
var obj = JSON.parse( data.toString() );
var shortcode = languages.filter( function(el) {
return el[0] == obj.language;
} ) [0][0];
var pyg = cp.spawn( &amp;amp;quot;pygmentize&amp;amp;quot;,
[ &amp;amp;quot;-l&amp;amp;quot;, shortcode,
&amp;amp;quot;-f&amp;amp;quot;, &amp;amp;quot;html&amp;amp;quot;,
&amp;amp;quot;-O&amp;amp;quot;, &amp;amp;quot;full,style=pastie&amp;amp;quot;,
&amp;amp;quot;-P&amp;amp;quot;, &amp;amp;quot;title=Snippet #&amp;amp;quot; + id ] );
pyg.stdout.addListener( &amp;amp;quot;data&amp;amp;quot;, function( coloured ) {
if( coloured )
res.write( coloured );
} );
pyg.addListener( 'exit', function() {
res.end();
});
pyg.stdin.write( obj.code );
pyg.stdin.end();
r.close();
});
});
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The Redis related code is pretty similar to &amp;lt;code&amp;gt;addSnippet()&amp;lt;/code&amp;gt;. In case the key doesn't exist, we will get a null. So we use &amp;lt;code&amp;gt;sendHeader()&amp;lt;/code&amp;gt; to send a &amp;lt;em&amp;gt;404 Page Not Found&amp;lt;/em&amp;gt;, and stop. Otherwise we send a healthy 200, tell the browser to expect HTML and then stream the data. Start the server, visit &amp;lt;code&amp;gt;/&amp;amp;lt;id&amp;amp;gt;&amp;lt;/code&amp;gt; and get your freshly highlighted code!&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;I want more&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Extend the simple pastebin to allow expiry (HINT: The Redis EXPIRE command), allow people to edit the bin and keep a diff history or more. One big improvement would be to cache the pygmentize results as that could really slow down a popular site with a large number of requests per second.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;a href=&quot;http://howtonode.org&quot;&amp;gt;How To Node&amp;lt;/a&amp;gt; has more great articles about writing other web apps. Tinker around with writing JavaScript bindings for C/C++ libraries or go build a Asynchronous, Distributed Googolplexbazillion search engine.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Full code for this article can be found at &amp;lt;a href=&quot;http://bitbucket.org/nikhilm/snip&quot;&amp;gt;Bitbucket&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;</description>
<pubDate>Tue Feb 23 2010 15:50:20 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>&quot;Do&quot; it fast!</title>
<category></category>
<author>tim@creationix.com (Tim Caswell)</author>
<guid>http://howtonode.org/do-it-fast</guid>
<link/>http://howtonode.org/do-it-fast
<description>&amp;lt;p&amp;gt;Now with the release of &amp;lt;a href=&quot;http://groups.google.com/group/nodejs/browse_thread/thread/e6cc6f04cd0ddf14&quot;&amp;gt;Node v0.1.30&amp;lt;/a&amp;gt; there is even more need for a library like &amp;lt;a href=&quot;http://github.com/creationix/do&quot;&amp;gt;Do&amp;lt;/a&amp;gt;. While working with the node community to decide on the best alternative to node promises, we decided that it's best left to library developers. So as of this morning, node no longer ships with promises, but uses a simple callback interface for all async functions.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;I took my async library that I've been developing throughout the Control Flow series and made it into a real library called &amp;lt;a href=&quot;http://github.com/creationix/do&quot;&amp;gt;Do&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Node callback interface&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;All async functions in node now use a simple callback based interface:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;do-it-fast/async.js&quot; class=&quot;code-link&quot;&amp;gt;async.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var fs = require('fs');
var sys = require('sys');
fs.readdir(&amp;amp;quot;/usr&amp;amp;quot;, function (err, files) {
if (err) throw err;
sys.puts(&amp;amp;quot;/usr files: &amp;amp;quot; + files);
});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;That is, after the arguments, there is a callback function expected. This callback function will be given the error if there was one, and if not, the result after that.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Creating an async function that exports this interface is simple too &amp;lt;a href=&quot;http://github.com/creationix/howtonode.org/blob/master/articles/do-it-fast/plain_callbacks.js&quot;&amp;gt;plain_callbacks.js&amp;lt;/a&amp;gt;:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;do-it-fast/safe-read.js&quot; class=&quot;code-link&quot;&amp;gt;safe-read.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Load 'fs', a built-in node library that has async functions
var fs = require('fs');
var sys = require('sys');
function safeRead(filename, callback) {
fs.readFile(filename, function (err, data) {
if (err) {
if (error.errno === process.ENOENT) {
// Ignore file not found errors and return an empty result
callback(null, &amp;amp;quot;&amp;amp;quot;);
} else {
// Pass other errors through as is
callback(err);
}
} else {
// Pass successes through as it too.
callback(null, data);
}
})
}
safeRead(__filename, function (err, text) {
if (err) {
throw err;
}
sys.puts(text);
})
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;/usr files: include,src,local,games,sbin,share,lib,bin
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;dl class=&quot;error&quot;&amp;gt;&amp;lt;dt&amp;gt;Error&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;ReferenceError: __filename is not defined&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;These callbacks are fast, simple, and to-the-point. However, your code can get pretty hairy when you start expanding beyond these trivial examples. These simple callback based functions can't be used with aggregate utilities, they can't be implicitly chained or grouped either.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;We can &amp;lt;code&amp;gt;Do&amp;lt;/code&amp;gt; better.&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;Do&amp;lt;/code&amp;gt; is a library that adds higher level abstraction and continuables. What I mean by a continuable is explained by the following:&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Continuables&amp;lt;/h3&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;function divide(a, b) { return function (callback, errback) {
// Use nextTick to prove that we're working asynchronously
process.nextTick(function () {
if (b === 0) {
errback(new Error(&quot;Cannot divide by 0&quot;));
} else {
callback(a / b);
}
});
}}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;Do&amp;lt;/code&amp;gt; expects async functions to not require the callback in the initial invocation, but instead return a continuable which can then be called with the &amp;lt;code&amp;gt;callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;errback&amp;lt;/code&amp;gt;. This is done by manually currying the function. The &quot;continuable&quot; is the function returned by the outer function. The body of the function won't be executed until you finish the application by attaching a callback.&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;divide(100, 10)(function (result) {
puts(&quot;the result is &quot; + result);
}, function (error) {
throw error;
});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;This style is extremely simple (doesn't require an external library like process.Promise to use), and is fairly powerful.&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;The initial function can have variable arguments.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;The continuable itself is portable until it's invoked by attaching callbacks.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;h3&amp;gt;Why is this better than plain-ol-callbacks?&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Well, let's convert the &amp;lt;code&amp;gt;safeRead&amp;lt;/code&amp;gt; example from above to continuables &amp;lt;a href=&quot;http://github.com/creationix/howtonode.org/blob/master/articles/do-it-fast/continuable_based.js&quot;&amp;gt;continuable_based.js&amp;lt;/a&amp;gt;:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var Do = require('do');
// Convert `readFile` from fs to use continuable style.
var fs = Do.convert(require('fs'), ['readFile']);
function safeRead(filename) { return function (callback, errback) {
fs.readFile(filename)(callback, function (error) {
if (error.errno === process.ENOENT) {
callback(&quot;&quot;);
} else {
errback(error);
}
})
}}
safeRead(__filename)(puts, errorHandler);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;You'll notice that this is a lot shorter and you don't have to constantly check for the error argument or pad your success results with a &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; argument. Also since we're passing through the success case as is, we can use the outer &amp;lt;code&amp;gt;callback&amp;lt;/code&amp;gt; as the inner &amp;lt;code&amp;gt;callback&amp;lt;/code&amp;gt;. In most cases you won't do this for success, but you will for &amp;lt;code&amp;gt;errback&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;What about the rest of &amp;lt;code&amp;gt;Do&amp;lt;/code&amp;gt;?&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;The real power of &amp;lt;code&amp;gt;Do&amp;lt;/code&amp;gt; and continuables comes when you're dealing with several async functions as once. Let's take our example from the &amp;lt;a href=&quot;http://howtonode.org/control-flow-part-iii&quot;&amp;gt;third control flow article&amp;lt;/a&amp;gt; and convert it to use the new &amp;lt;code&amp;gt;Do&amp;lt;/code&amp;gt; library:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var Do = require('do');
var fs = Do.convert(require('fs'), ['readdir', 'stat', 'readFile']);
// Checks the `stat` of a file path and outputs the file contents if it's
// a real file
function loadFile(path, callback, errback) {
fs.stat(path)(function (stat) {
// Output undefined when the path isn't a regular file
if (!stat.isFile()) {
callback();
return;
}
// Pass through the read to regular files as is.
fs.readFile(path)(callback, errback)
}, errback);
}
// Load an array of the contents of all files in a directory.
function loaddir(path) { return function (callback, errback) {
fs.readdir(path)(function (filenames) {
Do.filterMap(filenames, loadFile)(callback, errback);
}, errback);
}}
loaddir(__dirname)(p, errorHandler)
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h2&amp;gt;How to &amp;lt;code&amp;gt;Do&amp;lt;/code&amp;gt; (API)&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;The &amp;lt;code&amp;gt;Do&amp;lt;/code&amp;gt; library makes doing higher-level abstractions easy. All of these helpers are themselves continuables so you can attach callbacks by calling the returned, curried function.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Do.parallel(actions) {...}&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Takes an array of actions and runs them all in parallel. You can either pass in an array of actions, or several actions as function arguments.&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;If you pass in an array, then the output will be an array of all the results&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;If you pass in separate arguments, then the output will have several arguments.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Example:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Multiple arguments
Do.parallel(
Do.read(&quot;/etc/passwd&quot;),
Do.read(__filename)
)(function (passwd, self) {
// Do something
}, errorHandler);
// Single argument
var actions = [
Do.read(&quot;/etc/passwd&quot;),
Do.read(&quot;__filename&quot;)
];
Do.parallel(actions)(function (results) {
// Do something
}, errorHandler);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h3&amp;gt;Do.chain(actions) {...}&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Chains together several actions feeding the output of the first to the input of the second and the final output to the continuables callback.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Example:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Multiple arguments
Do.chain(
Do.read(__filename),
function (text) {
return Do.save(&quot;newfile&quot;, text);
},
function () {
return Do.stat(&quot;newfile&quot;);
}
)(function (stat) {
// Do something
}, errorHandler);
// Single argument
var actions = [
Do.read(__filename),
function (text) {
return Do.save(&quot;newfile&quot;, text);
},
function () {
return Do.stat(&quot;newfile&quot;);
}
];
Do.chain(actions)(function (stat) {
// Do something
}, errorHandler);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h3&amp;gt;Do.map(array, fn) {...}&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Takes an array and does an array map over it using the async callback &amp;lt;code&amp;gt;fn&amp;lt;/code&amp;gt;. The signature of &amp;lt;code&amp;gt;fn&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;function fn(item, callback, errback)&amp;lt;/code&amp;gt; or any regular continuable.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Example:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Direct callback filter
var files = ['users.json', 'pages.json', 'products.json'];
function loadFile(filename, callback, errback) {
fs.read(filename)(function (data) {
callback([filename, data]);
}, errback);
}
Do.map(files, loadFile)(function (contents) {
// Do something
}, errorHandler);
// continuable based filter
var files = ['users.json', 'pages.json', 'products.json'];
Do.map(files, fs.read)(function (contents) {
// Do something
}, errorHandler);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h3&amp;gt;Do.filter(array, fn) {...}&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Takes an array and does an array filter over it using the async callback &amp;lt;code&amp;gt;fn&amp;lt;/code&amp;gt;. The signature of &amp;lt;code&amp;gt;fn&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;function fn(item, callback, errback)&amp;lt;/code&amp;gt; or any regular continuable.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Example:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Direct callback filter
var files = ['users.json', 'pages.json', 'products.json'];
function isFile(filename, callback, errback) {
fs.stat(filename)(function (stat) {
callback(stat.isFile());
}, errback);
}
Do.filter(files, isFile)(function (filtered_files) {
// Do something
}, errorHandler);
// Continuable based filter
var files = ['users.json', 'pages.json', 'products.json'];
function isFile(filename) { return function (callback, errback) {
fs.stat(filename)(function (stat) {
callback(stat.isFile());
}, errback);
}}
Do.filter(files, isFile)(function (filtered_files) {
// Do something
}, errorHandler);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h3&amp;gt;Do.filterMap(array, fn) {...}&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Takes an array and does a combined filter and map over it. If the result
of an item is undefined, then it's filtered out, otherwise it's mapped in.
The signature of &amp;lt;code&amp;gt;fn&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;function fn(item, callback, errback)&amp;lt;/code&amp;gt; or any regular continuable.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Example:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Direct callback filter
var files = ['users.json', 'pages.json', 'products.json'];
function check_and_load(filename, callback, errback) {
fs.stat(filename)(function (stat) {
if (stat.isFile()) {
loadFile(filename, callback, errback);
} else {
callback();
}
}, errback);
}
Do.filterMap(files, check_and_load)(function (filtered_files_with_data) {
// Do something
}, errorHandler);
// Continuable based filter
var files = ['users.json', 'pages.json', 'products.json'];
function check_and_load(filename) { return function (callback, errback) {
fs.stat(filename)(function (stat) {
if (stat.isFile()) {
loadFile(filename, callback, errback);
} else {
callback();
}
}, errback);
}}
Do.filterMap(files, check_and_load)(function (filtered_files_with_data) {
// Do something
}, errorHandler);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h2&amp;gt;Using with node libraries&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Do has a super nifty &amp;lt;code&amp;gt;Do.convert&amp;lt;/code&amp;gt; function that takes a library and converts it to use Do style continuables. For example, if you wanted to use &amp;lt;code&amp;gt;fs.readFile&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fs.writeFile&amp;lt;/code&amp;gt;, then you would do this:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var fs = Do.convert(require('fs'), ['readFile', 'writeFile']);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Do will give you a copy of &amp;lt;code&amp;gt;fs&amp;lt;/code&amp;gt; that has &amp;lt;code&amp;gt;readFile&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;writeFile&amp;lt;/code&amp;gt; converted to Do style. It's that easy!&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;For library writers&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;All async functions in node follow a common interface:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;method(arg1, arg2, arg3, ..., callback)
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Where &amp;lt;code&amp;gt;callback&amp;lt;/code&amp;gt; is of the form:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;callback(err, result1, result2, ...)
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;This is done to keep node simple and to allow for interoperability between the various async abstractions like Do continuables and CommonJS promises.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;If you're writing a library, make sure to export all your async functions following the node interface. Then anyone using your library can know what format to expect.&amp;lt;/p&amp;gt;</description>
<pubDate>Mon Feb 22 2010 16:52:08 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Blog rolling with mongoDB, express and Node.js</title>
<category></category>
<author>ciaranj@gmail.com (Ciaran Jessup)</author>
<guid>http://howtonode.org/express-mongodb</guid>
<link/>http://howtonode.org/express-mongodb
<description>&amp;lt;p&amp;gt;In this article I hope to take you through the steps required to get a fully-functional (albeit feature-light) persistent blogging system running on top of &amp;lt;a href=&quot;http://nodejs.org&quot;&amp;gt;node&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;The technology stack that we'll be using will be &amp;lt;a href=&quot;http://nodejs.org&quot;&amp;gt;node&amp;lt;/a&amp;gt; + &amp;lt;a href=&quot;http://github.com/visionmedia/express&quot;&amp;gt;express&amp;lt;/a&amp;gt; + &amp;lt;a href=&quot;http://www.mongodb.org&quot;&amp;gt;mongoDB&amp;lt;/a&amp;gt; all of which are exciting, fast and highly scalable. You'll also get to use &amp;lt;a href=&quot;http://github.com/visionmedia/haml.js&quot;&amp;gt;haml-js&amp;lt;/a&amp;gt; and &amp;lt;a href=&quot;http://github.com/visionmedia/sass.js&quot;&amp;gt;sass.js&amp;lt;/a&amp;gt; for driving the templated views and styling! We will be using &amp;lt;a href=&quot;http://wiki.github.com/visionmedia/kiwi&quot;&amp;gt;kiwi&amp;lt;/a&amp;gt; to easy the package management and installation issues.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;This article will be fairly in-depth so you may want to get yourself a rather large mug of whatever beverage you prefer before you settle down :)&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Getting Started / Pre-Requisites&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Before we start with the code it's important to make sure you have &amp;lt;a href=&quot;http://git-scm.com/&quot;&amp;gt;git&amp;lt;/a&amp;gt; installed, an up-to-date installation of &amp;lt;a href=&quot;http://nodejs.org&quot;&amp;gt;node&amp;lt;/a&amp;gt; and a running &amp;lt;a href=&quot;http://www.mongodb.org&quot;&amp;gt;mongodb&amp;lt;/a&amp;gt; server on your development environment.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;git&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Whilst not a mandatory requirement I will be using git to pull down code from various location. Sadly the installation, configuration and setup of git is way beyond the scope of this article and I recommend reading up on that before embarking on this article if you're not familiar with git!&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;mongoDB&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Installation is as simple as downloading the &amp;lt;a href=&quot;http://www.mongodb.org/display/DOCS/Downloads&quot;&amp;gt;installer from here&amp;lt;/a&amp;gt;. For this tutorial I've been using v1.2.2 on MacOSX but any recent version should work. Once installed you can just execute 'mongod' to have a local instance up and running.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;node.js&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;I'll assume that you already have an installed version of node.js (why else would you be looking at a how-to?! ;) ) However as &amp;lt;a href=&quot;http://nodejs.org&quot;&amp;gt;node&amp;lt;/a&amp;gt; is subject to a reasonably high rate of change for the purposes of this article everything has been written to run against the &amp;lt;a href=&quot;http://github.com/ry/node/tree/v0.1.91&quot;&amp;gt;'v0.1.91' tag&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;kiwi&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;The original version of this article required various dependencies to be installed by hand from github repositories, package management has moved on within node.js since that time and we will use this to our advantage by following the instructions on how to install the &amp;lt;a href=&quot;http://wiki.github.com/visionmedia/kiwi/getting-started&quot;&amp;gt;kiwi package manager&amp;lt;/a&amp;gt;.
Once kiwi is installed you should be able to execute:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;kiwi search
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;From your console and see a list of &amp;lt;a href=&quot;http://nodejs.org&quot;&amp;gt;node&amp;lt;/a&amp;gt; packages that can be installed, if you cannot then it would be a good plan to figure out why not before proceeding.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Getting hold of express&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Installing express on your system is as easy as:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;kiwi install express 0.9.0
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Now we can begin with the process of writing our blog, let the good times (blog)roll.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Defining our application&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;We're going to build a very simple blogging application (perhaps we'll build on this in a future article?). It is going to support the reading of blog articles, posting of blog articles and commenting on them. There will be no security, authentication or authorization. Hopefully this will demonstrate enough of the technology stack to let you move forward quickly.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;The data types&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Because we're dealing with a &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Document-oriented_database&quot;&amp;gt;document orientated&amp;lt;/a&amp;gt; database rather than a &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Relational_database_management_system&quot;&amp;gt;relational&amp;lt;/a&amp;gt; database we don't need to worry about what 'tables' we will need to persist this data to the database or the relationships between records within those tables. In fact we only have 1 datatype in the application at all, the article:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;{
_id: 0,
title: '',
body: '',
comments: [{
person: '',
comment: '',
created_at: new Date()
}],
created_at: new Date()
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;There are plenty of other document configurations we could've gone for but this will provide us with a good foundation (for example there's no notion of article authors.). Also the &amp;lt;code&amp;gt;created_at&amp;lt;/code&amp;gt; field could most probably be omitted as the default 'Primary Key factory' that the mongo-db-native client that we're using generates time-based object-ids, but for simplicity we'll go with a 'proper' date.&amp;lt;/p&amp;gt;
&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;It should be noted that one oft-reported issue with mongoDB is the size of the data on the disk. As we're dealing with a &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Document-oriented_database&quot;&amp;gt;document orientated&amp;lt;/a&amp;gt; database each and every record stores all the field-names with the data so there is no re-use. This means that it can often be more space-efficient to have properties such as 't', or 'b' rather than 'title' or 'body', however for fear of confusion I would avoid this unless truly required!&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&amp;lt;h3&amp;gt;The operations&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;There is a discrete set of operations (or things we want to achieve) that fall within the scope of this article, they are (in the order that we will tackle them):&amp;lt;/p&amp;gt;
&amp;lt;ol&amp;gt;
&amp;lt;li&amp;gt;Create a new article.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Show the list of all the articles.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Show an individual article and its comments.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Comment on an article&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;p&amp;gt;Now that we know what we're trying to achieve lets try and achieve that goal in a step-by-step fashion.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;From small acorns do giant oak trees grow&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;Well alright, fairly small blogging apps can grow!&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;In express a 'normal' application consists of a call to &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt;, followed by a series of method calls that declare &amp;lt;code&amp;gt;routes&amp;lt;/code&amp;gt; and what happens to requests that match the route followed by a call to &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Thus one of the simplest express applications (when using kiwi) could be written as follows:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/simple-express.js&quot; class=&quot;code-link&quot;&amp;gt;simple-express.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var kiwi= require('kiwi')
kiwi.require('express');
require('express/plugins')
configure(function(){
use(MethodOverride);
use(ContentLength);
use(Logger);
set('root', __dirname);
})
get('/', function(){
this.halt(200, &amp;amp;quot;Hello World!&amp;amp;quot;);
})
run();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The above code declares a single &amp;lt;code&amp;gt;route&amp;lt;/code&amp;gt; that operates on &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; requests to the address &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; from the browser and will just return a simple (non-HTML) text string and a response code of 200 to the client.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Convention seems to be to place this code into a file named &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; at the root of your express folder. If you do this and then execute it:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;node app.js
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;When you browse to &amp;lt;a href=&quot;http://localhost:3000&quot;&amp;gt;localhost:3000&amp;lt;/a&amp;gt; you should see that old favourite 'Hello World!'. This file is the starting point of the blogging application and we shall build on it now :)&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;A chapter in which we build on our humble beginnings&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Now that we have a fully working web server we should probably look at doing something with it. In this section we will learn how to use &amp;lt;a href=&quot;http://haml-lang.com/&quot;&amp;gt;Haml&amp;lt;/a&amp;gt; to render our data and create forms to post the data back to the server, initially we will store this in memory.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;The layout of express applications is fairly familiar and is usually of the form:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;express /* The top level folder containing our app */
|-- app.js /* The application code itself */
|-- lib /* Third-party dependencies */
|-- public /* Publicly accessible resources */
| |-- images
| `-- javascript
`-- views /* The templates for the 'views' */
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Please take a moment to create the folders that you require, these will need creating:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;mkdir public
mkdir public/javascript
mkdir public/images
mkdir views
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;h3&amp;gt;Of providers and data&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Because the intention of this article is to show how one might use a persistent approach in node.js we shall start with an abstraction: provider. These 'providers' are going to responsible for returning and updating the data. Initially we'll create a dummy in-memory version just to bootstrap us up and running, but then we'll move over to using a real persistence layer without changing the calling code.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/articleprovider-memory.js&quot; class=&quot;code-link&quot;&amp;gt;articleprovider-memory.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var articleCounter = 1;
ArticleProvider = function(){};
ArticleProvider.prototype.dummyData = [];
ArticleProvider.prototype.findAll = function(callback) {
callback( null, this.dummyData )
};
ArticleProvider.prototype.findById = function(id, callback) {
var result = null;
for(var i =0;i&amp;amp;lt;this.dummyData.length;i++) {
if( this.dummyData[i]._id == id ) {
result = this.dummyData[i];
break;
}
}
callback(null, result);
};
ArticleProvider.prototype.save = function(articles, callback) {
var article = null;
if( typeof(articles.length)==&amp;amp;quot;undefined&amp;amp;quot;)
articles = [articles];
for( var i =0;i&amp;amp;lt; articles.length;i++ ) {
article = articles[i];
article._id = articleCounter++;
article.created_at = new Date();
if( article.comments === undefined )
article.comments = [];
for(var j =0;j&amp;amp;lt; article.comments.length; j++) {
article.comments[j].created_at = new Date();
}
this.dummyData[this.dummyData.length]= article;
}
callback(null, articles);
};
/* Lets bootstrap with dummy data */
new ArticleProvider().save([
{title: 'Post one', body: 'Body one', comments:[{author:'Bob', comment:'I love it'}, {author:'Dave', comment:'This is rubbish!'}]},
{title: 'Post two', body: 'Body two'},
{title: 'Post three', body: 'Body three'}
], function(error, articles){});
exports.ArticleProvider = ArticleProvider;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;If the above code is saved to a file named &amp;lt;code&amp;gt;articleprovider-memory.js&amp;lt;/code&amp;gt; in the same folder as the &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; we created earlier and &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; is modified to look as follows:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/app-simple.js&quot; class=&quot;code-link&quot;&amp;gt;app-simple.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var kiwi= require('kiwi')
kiwi.require('express');
require('express/plugins')
var ArticleProvider = require('./articleprovider-memory').ArticleProvider;
configure(function(){
use(MethodOverride);
use(ContentLength);
use(Logger);
set('root', __dirname);
})
var articleProvider= new ArticleProvider();
get('/', function(){
var self = this;
articleProvider.findAll(function(error, docs){
self.halt( 200, require('sys').inspect(docs) );
})
})
run();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;If the app is re-run and you browse to &amp;lt;a href=&quot;http://localhost:3000&quot;&amp;gt;localhost:3000&amp;lt;/a&amp;gt; you will see the object structure of 3 blog posts that the memory provider starts off with, magic!&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;A view to a kill&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Now we have a way of reading and storing data (patience, memory is only the beginning!) we'll want a way of displaying and creating the data properly. Initially we'll start by just providing an index view of all the blog articles. To do this create the following two files in your views sub-directory (be very careful about the indentation, that first lines should be up against the left-hand margin!):&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/views/layout.html.haml&quot; class=&quot;code-link&quot;&amp;gt;views/layout.html.haml&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;%html
%head
%title= title
%body
#wrapper
!= body
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;and&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/views/blogs_index.html.haml&quot; class=&quot;code-link&quot;&amp;gt;views/blogs_index.html.haml&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;%h1= title
#articles
- each article in articles
%div.article
%div.created_at= article.created_at
%div.title= article.title
%div.body= article.body
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Next change your &amp;lt;code&amp;gt;get('/')&amp;lt;/code&amp;gt; routing rule in your &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; to be as follows:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/app2.js&quot; class=&quot;code-link&quot;&amp;gt;app2.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#root&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;get('/', function(){
var self = this;
articleProvider.findAll(function(error, docs){
self.render('blogs_index.html.haml', {
locals: {
title: 'Blog',
articles: docs
}
});
})
})
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Now you should be able to restart the server and browser to &amp;lt;a href=&quot;http://localhost:3000&quot;&amp;gt;localhost:3000&amp;lt;/a&amp;gt;. Et voila! We'll not win any design awards, but you should now see a list of 3 very 'functional' blog postings (don't worry we'll come back to the style in a moment).&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;There are two important things to note that we've just done;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;The first is the change to our application's routing rules. What we've done is say that for any browser requests that come in to the route ('/') we should ask the data provider for all the articles it knows about (a future improvement might be 'the most recent 10 posts etc.') and to 'render' those returned articles using the &amp;lt;a href=&quot;http://github.com/visionmedia/haml.js&quot;&amp;gt;haml-js&amp;lt;/a&amp;gt; template &amp;lt;code&amp;gt;blogs_index.html.haml&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;The second is the usage of a 'layout' &amp;lt;a href=&quot;http://github.com/visionmedia/haml.js&quot;&amp;gt;haml-js&amp;lt;/a&amp;gt; file &amp;lt;code&amp;gt;layout.html.haml&amp;lt;/code&amp;gt;. This file will be used whenever a call to 'render' is made (unless over-ridden in that particular call) and provides a simple mechanism for common style across all page requests.&amp;lt;/p&amp;gt;
&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;If you're familiar with &amp;lt;a href=&quot;http://haml-lang.com/&quot;&amp;gt;Haml&amp;lt;/a&amp;gt; then you may want to skip this section, otherwise please read-on! &amp;lt;a href=&quot;http://haml-lang.com/&quot;&amp;gt;Haml&amp;lt;/a&amp;gt; is yet-another templating language, however this one is driven by the rule that 'Markup should be beautiful'. It provides a lightweight syntax for declaring markup with a bare minimum of typed characters.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;a href=&quot;http://github.com/visionmedia/haml.js&quot;&amp;gt;haml-js&amp;lt;/a&amp;gt; is a server-side JavaScript partial/mostly-complete implementation of &amp;lt;a href=&quot;http://haml-lang.com/&quot;&amp;gt;Haml&amp;lt;/a&amp;gt;. Reading a &amp;lt;a href=&quot;http://github.com/visionmedia/haml.js&quot;&amp;gt;haml-js&amp;lt;/a&amp;gt; template is simple. The hierarchy of elements is expressed as indentation on the left hand-side; that is, everything that starts in a given column shares the same parent. Each line of &amp;lt;a href=&quot;http://haml-lang.com/&quot;&amp;gt;Haml&amp;lt;/a&amp;gt; represents either a new element in the (eventual) HTML document or a function within &amp;lt;a href=&quot;http://haml-lang.com/&quot;&amp;gt;Haml&amp;lt;/a&amp;gt; (which offers conditions and loops etc). Effectively &amp;lt;a href=&quot;http://github.com/visionmedia/haml.js&quot;&amp;gt;haml-js&amp;lt;/a&amp;gt; takes a JSON object and binds it to any &amp;lt;code&amp;gt;literal&amp;lt;/code&amp;gt; text in the &amp;lt;a href=&quot;http://github.com/visionmedia/haml.js&quot;&amp;gt;haml-js&amp;lt;/a&amp;gt; template, applies the rules that define &amp;lt;a href=&quot;http://haml-lang.com/&quot;&amp;gt;Haml&amp;lt;/a&amp;gt; and then processes the resulting bag of stuff to produce a well-formed and valid HTML document of the specified DOCTYPE. (Yay!)&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&amp;lt;p&amp;gt;As is probably obvious we need a little styling to be applied here, to do that we'll need to change our layout a little to request a stylesheet, add a new rule to service this request and add a Sass template to the &amp;lt;code&amp;gt;views&amp;lt;/code&amp;gt; folder in order to generate the css.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/views/style.css.sass&quot; class=&quot;code-link&quot;&amp;gt;views/style.css.sass&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;body
:font-family &amp;amp;quot;Helvetica Neue&amp;amp;quot;, &amp;amp;quot;Lucida Grande&amp;amp;quot;, &amp;amp;quot;Arial&amp;amp;quot;
:font-size 13px
:text-align center
=text-stroke 1px rgba(255, 255, 255, 0.1)
:color #555
h1, h2
:margin 0
:font-size 22px
:color #343434
h1
:text-shadow 1px 2px 2px #ddd
:font-size 60px
#articles
:text-align left
:margin-left auto
:margin-right auto
:width 320px
.article
:margin 20px
.created_at
:display none
.title
:font-weight bold
:text-decoration underline
:background-color #eee
.body
:background-color #ffa
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;And add a new route to app.js:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/app2.js&quot; class=&quot;code-link&quot;&amp;gt;app2.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#css&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;get('/*.css', function(file){
this.render(file + '.css.sass', { layout: false });
});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Again after restarting your app and browsing to &amp;lt;a href=&quot;http://localhost:3000&quot;&amp;gt;localhost:3000&amp;lt;/a&amp;gt; you should see the posts, with a little more style (admittedly not much more!).&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;A couple of things to notice here:&amp;lt;/p&amp;gt;
&amp;lt;ol&amp;gt;
&amp;lt;li&amp;gt;We setup a route to handle the request for the css as a regular expression match. We then used the matched url segment to load a Sass file from the available views and &amp;lt;code&amp;gt;express&amp;lt;/code&amp;gt; dynamically converts the Sass into CSS for us on the fly. In a production environment there are configuration options that can be passed to the &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt; method to make sure these views are cached but during development its rather useful to be able to change your Sass on the fly :)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;As express is treating the sass to CSS rendering in exactly the same manner as the Haml to HTML rendering we need to suppress the default &amp;lt;code&amp;gt;layout&amp;lt;/code&amp;gt; behaviour as there is no meaningful layout here for our Sass.&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;Sass is to CSS as Haml is to HTML. However reading Sass can be a little more complex as the hierarchy that is being described is really individual selectors. Lines that start at the same column and begin with a &amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt; are rules, these rules are applied to the hierarchy that they're found under, for example in the above Sass example the bottom most line of Sass &amp;lt;code&amp;gt;:background-color #ffa&amp;lt;/code&amp;gt; is equivalent to the CSS &amp;lt;code&amp;gt;#articles .article .body {background-color: #ffa;}&amp;lt;/code&amp;gt; this equivalence is due to the position of the start of this line relative to its parent lines :) (Easy really!)&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&amp;lt;h3&amp;gt;Great, so how do I make my first post?&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Now we can view a list of blog posts it would be nice to have a simple form for making new posts and being re-directed back to the new list. To achieve this we'll need a new view (to let us create a post) and two new routes (one to accept the post data, the other to return the form).&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/views/blog_new.html.haml&quot; class=&quot;code-link&quot;&amp;gt;views/blog_new.html.haml&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;%h1= title
%form{ method: 'post' }
%div
%div
%span Title :
%input{ type: 'text', name: 'title', id: 'editArticleTitle' }
%div
%span Body :
%textarea{ name: 'body', rows: 20, id: 'editArticleBody' }
%div#editArticleSubmit
%input{ type: 'submit', value: 'Send' }
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Add two new routes to app.js&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/app2.js&quot; class=&quot;code-link&quot;&amp;gt;app2.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#blog&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;get('/blog/new', function(){
this.render('blog_new.html.haml', {
locals: {
title: 'New Post'
}
});
});
post('/blog/new', function(){
var self = this;
articleProvider.save({
title: this.param('title'),
body: this.param('body')
}, function(error, docs) {
self.redirect('/')
});
});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Upon restarting your app if you browse to &amp;lt;a href=&quot;http://localhost:3000/blog/new&quot;&amp;gt;new post&amp;lt;/a&amp;gt; you will be able to create new blog articles, awesome! Looking at the post route we can see that upon successfully saving we redirect back to the index page where all the articles are displayed.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;If I've lost you along the way you can get a zip of this fully working (but non-persisting) blog here: &amp;lt;a href=&quot;http://github.com/creationix/howtonode.org/tree/master/articles/express-mongodb/express-mongodb-1.zip&quot;&amp;gt;Checkpoint 1&amp;lt;/a&amp;gt;. This patch should apply cleanly to the previously described SHA of express :)&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Adding permanent persistence to the mix&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;I promised that by the end of this article we'd be persisting our data across restarts of node, I've not yet delivered on this promise but now I will ..hopefully ;)&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;To do this we need to install a dependency on &amp;lt;a href=&quot;http://github.com/christkv/node-mongodb-native&quot;&amp;gt;node-mongodb-native&amp;lt;/a&amp;gt;, which will allow our burgeoning application to access &amp;lt;a href=&quot;http://www.mongodb.org&quot;&amp;gt;mongoDB&amp;lt;/a&amp;gt;. Once again our friend kiwi comes to the rescue. If we open the console up and enter the &amp;lt;code&amp;gt;express&amp;lt;/code&amp;gt; directory we created earlier we will be able to type the following commands to install the driver.&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;#!sh
kiwi install mongodb-native 0.7.0
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Now we need to replace our old memory based data provider with one thats capable of using mongodb:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/articleprovider-mongodb.js&quot; class=&quot;code-link&quot;&amp;gt;articleprovider-mongodb.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var Db= require('mongodb/db').Db,
ObjectID= require('mongodb/bson/bson').ObjectID,
Server= require('mongodb/connection').Server;
ArticleProvider = function(host, port) {
this.db= new Db('node-mongo-blog', new Server(host, port, {auto_reconnect: true}, {}));
this.db.open(function(){});
};
ArticleProvider.prototype.getCollection= function(callback) {
this.db.collection('articles', function(error, article_collection) {
if( error ) callback(error);
else callback(null, article_collection);
});
};
ArticleProvider.prototype.findAll = function(callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback(error)
else {
article_collection.find(function(error, cursor) {
if( error ) callback(error)
else {
cursor.toArray(function(error, results) {
if( error ) callback(error)
else callback(null, results)
});
}
});
}
});
};
ArticleProvider.prototype.findById = function(id, callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback(error)
else {
article_collection.findOne({_id: ObjectID.createFromHexString(id)}, function(error, result) {
if( error ) callback(error)
else callback(null, result)
});
}
});
};
ArticleProvider.prototype.save = function(articles, callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback(error)
else {
if( typeof(articles.length)==&amp;amp;quot;undefined&amp;amp;quot;)
articles = [articles];
for( var i =0;i&amp;amp;lt; articles.length;i++ ) {
article = articles[i];
article.created_at = new Date();
if( article.comments === undefined ) article.comments = [];
for(var j =0;j&amp;amp;lt; article.comments.length; j++) {
article.comments[j].created_at = new Date();
}
}
article_collection.insert(articles, function() {
callback(null, articles);
});
}
});
};
exports.ArticleProvider = ArticleProvider;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;We will also require a minor change to &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; to use this new replacement provider. &amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/app.js&quot; class=&quot;code-link&quot;&amp;gt;app.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var kiwi= require('kiwi')
kiwi.require('express');
kiwi.seed('mongodb-native')
require('express/plugins')
var ArticleProvider= require('./articleprovider-mongodb').ArticleProvider;
configure(function(){
use(MethodOverride);
use(ContentLength);
use(Logger);
set('root', __dirname);
})
var articleProvider= new ArticleProvider('localhost', 27017);
get('/', function(){
var self = this;
articleProvider.findAll(function(error, docs){
self.render('blogs_index.html.haml', {
locals: {
title: 'Blog',
articles: docs
}
});
})
})
get('/*.css', function(file){
this.render(file + '.css.sass', { layout: false });
});
get('/blog/new', function(){
this.render('blog_new.html.haml', {
locals: {
title: 'New Post'
}
});
});
post('/blog/new', function(){
var self = this;
articleProvider.save({
title: this.param('title'),
body: this.param('body')
}, function(error, docs) {
self.redirect('/')
});
});
run();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;As you can see we had to make only the smallest of changes to move away from a temporary in-memory JSON store to the fully persistent and highly scalable mongoDB store.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Let us pause for a second to take a look at two of the methods we've just written to access &amp;lt;a href=&quot;http://www.mongodb.org&quot;&amp;gt;mongoDB&amp;lt;/a&amp;gt;, it is perhaps not immediately obvious what is happening as there are a &amp;lt;em&amp;gt;lot&amp;lt;/em&amp;gt; of different things going on:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/articleprovider-mongodb-final.js&quot; class=&quot;code-link&quot;&amp;gt;articleprovider-mongodb-final.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#getCollection&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;
ArticleProvider.prototype.getCollection= function(callback) {
this.db.collection('articles', function(error, article_collection) {
if( error ) callback(error);
else callback(null, article_collection);
});
};
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;ol&amp;gt;
&amp;lt;li&amp;gt;Declares the &amp;lt;code&amp;gt;getCollection&amp;lt;/code&amp;gt; method on the provider's &amp;lt;code&amp;gt;prototype&amp;lt;/code&amp;gt;. This method only accepts one mandatory argument, a function that will be called back with the the results upon completion (or error in the case of an error.) This approach is a common idiom in &amp;lt;a href=&quot;http://nodejs.org&quot;&amp;gt;node&amp;lt;/a&amp;gt; but can be confusing to look at initially.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;In mongoDB there are no tables as such, (hence schema-less) but there are &amp;lt;code&amp;gt;collections&amp;lt;/code&amp;gt;. A &amp;lt;code&amp;gt;collection&amp;lt;/code&amp;gt; is a logical grouping of similar documents, but there are very few constraints on what types of document is put in these &amp;lt;code&amp;gt;collections&amp;lt;/code&amp;gt;. For our purpose we will have a single &amp;lt;code&amp;gt;collection&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;articles&amp;lt;/code&amp;gt;. By calling &amp;lt;code&amp;gt;collection&amp;lt;/code&amp;gt; on the &amp;lt;code&amp;gt;db&amp;lt;/code&amp;gt; object and passing in our collection name &amp;lt;code&amp;gt;articles&amp;lt;/code&amp;gt; and a callback to deal with the response mongoDb will quietly create the collection from scratch and return it if there wasn't a collection of that name already or it will just return a reference to an existing collection. (This behaviour can actually be controlled by configuring mongoDB to be &amp;lt;code&amp;gt;strict&amp;lt;/code&amp;gt;.)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;If an error is passed back then we need to propagate it back to the previously passed callback.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Otherwise pass the collection that came from &amp;lt;a href=&quot;http://www.mongodb.org&quot;&amp;gt;mongoDB&amp;lt;/a&amp;gt; back to the previously passed callback.&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;p&amp;gt;and&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/articleprovider-mongodb-final.js&quot; class=&quot;code-link&quot;&amp;gt;articleprovider-mongodb-final.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#addCommentToArticle&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;
ArticleProvider.prototype.addCommentToArticle = function(articleId, comment, callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback( error );
else {
article_collection.update(
{_id: ObjectID.createFromHexString(articleId)},
{&amp;amp;quot;$push&amp;amp;quot;: {comments: comment}},
function(error, article){
if( error ) callback(error);
else callback(null, article)
});
}
});
};
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;ol&amp;gt;
&amp;lt;li&amp;gt;Declares the &amp;lt;code&amp;gt;findById&amp;lt;/code&amp;gt; method on the provider's &amp;lt;code&amp;gt;prototype&amp;lt;/code&amp;gt;. This method is going to take in one argument the &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; of the article we wish to retrieve and a callback that will receive the data.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;We call the previously defined method &amp;lt;code&amp;gt;getCollection&amp;lt;/code&amp;gt; to retrieve our collection of records from the &amp;lt;a href=&quot;http://www.mongodb.org&quot;&amp;gt;mongoDB&amp;lt;/a&amp;gt; server, this method is asynchronous so we have to pass in the callback that will be called when it completes.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;If there was an error we give up here and pass it back to the callback.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;An &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; keyword, if I need to explain this I'm very impressed you've made it this far before falling asleep :)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;The &amp;lt;code&amp;gt;article_collection&amp;lt;/code&amp;gt; that is passed in the callback from the previous call to &amp;lt;code&amp;gt;getCollection(...)&amp;lt;/code&amp;gt; (think &amp;lt;code&amp;gt;FROM clause&amp;lt;/code&amp;gt;) exposes various methods for manipulating the data stored inside of the database. Here we've chosen to use &amp;lt;code&amp;gt;findOne&amp;lt;/code&amp;gt; which when given some criteria to search on will return the sole record that matches those criteria, but there are others such as &amp;lt;code&amp;gt;find&amp;lt;/code&amp;gt; which returns a &amp;lt;code&amp;gt;cursor&amp;lt;/code&amp;gt; that can be iterated over etc.
5a. This line also contains the &amp;lt;code&amp;gt;specification&amp;lt;/code&amp;gt; argument (think &amp;lt;code&amp;gt;criteria&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;WHERE clause&amp;lt;/code&amp;gt;) used by the &amp;lt;code&amp;gt;findOne&amp;lt;/code&amp;gt; method, here we're using the passed in &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; (which is a hexadecimal string ultimately coming from the browser so needs to be converted to the real type that our &amp;lt;code&amp;gt;_id&amp;lt;/code&amp;gt; fields are being stored as.) It basically states 'Find me the document in the collection who has a property named &amp;lt;code&amp;gt;_id&amp;lt;/code&amp;gt; and a value equivalent to an &amp;lt;code&amp;gt;ObjectId&amp;lt;/code&amp;gt; constructed with the passed in hexadecimal string.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;If there was an error we give up here and pass it back to the callback.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Now we have the record we searched for in the database we pass it back to the callback we originally passed into the (in our case this callback would do the page rendering.)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;,9,10 &amp;amp;amp; 11. Meh! some brackets and stuff :)&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;p&amp;gt;I hope this explains a little better what is now going on inside our new provider code.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Adding comments&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;We're about halfway through the set of (4) operations we defined earlier but you'll be pleased to know that we've completed the majority of the work, everything from here on in is just minor improvements :)&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Just to re-cap over we've done so far:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;Create a new article.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Show the list of all the articles.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;and we still need to do:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;Show an individual article and its comments.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Comment on an article.&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;So, lets crack on!&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Showing an individual article and its comments&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Displaying an individual article isn't much different to displaying one of the articles within the list of articles that we've already done, so we'll pinch some of that template. In addition to displaying the title and body though we will also want to render all the existing comments and provide a form for readers to add their own comment.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;We'll also need a new route to allow the article to be referenced by a URL and we'll need to tweak the rendered list so our titles on the list can now be hyperlinks to the real article's own page.&amp;lt;/p&amp;gt;
&amp;lt;blockquote&amp;gt;
&amp;lt;p&amp;gt;One thing that we should touch on here is &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Surrogate_key&quot;&amp;gt;surrogate&amp;lt;/a&amp;gt; vs &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Natural_key&quot;&amp;gt;natural&amp;lt;/a&amp;gt; keys. It seems that with &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Document-oriented_database&quot;&amp;gt;document orientated&amp;lt;/a&amp;gt; databases it is encouraged where possible to use &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Natural_key&quot;&amp;gt;natural&amp;lt;/a&amp;gt; keys however in this case we've not got any sensible one to use (&amp;lt;em&amp;gt;unless you fancy title to be unique enough you crazy fool&amp;lt;/em&amp;gt;.)&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Normally this wouldn't be that much of an issue as &amp;lt;a href=&quot;http://en.wikipedia.org/wiki/Surrogate_key&quot;&amp;gt;surrogate&amp;lt;/a&amp;gt; keys are usually fairly sane things like auto-incremented integers, unfortunately the &amp;lt;em&amp;gt;default&amp;lt;/em&amp;gt; primary key provider that we're using generates universally unique (and universally opaque) binary objects / large numbers in byte arrays. These 'numbers' don't really translate well into HTML so we need to use some utility methods on the &amp;lt;code&amp;gt;ObjectId&amp;lt;/code&amp;gt; class to translate to and from a hex-string into the id that can located on the database.&amp;lt;/p&amp;gt;
&amp;lt;/blockquote&amp;gt;
&amp;lt;p&amp;gt;We need to update the index page's view:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/views/blogs_index-final.html.haml&quot; class=&quot;code-link&quot;&amp;gt;views/blogs_index-final.html.haml&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;-# views/blogs_index.html.haml
%h1= title
#articles
- each article in articles
%div.article
%div.created_at= article.created_at
%div.title
%a{href:&amp;amp;quot;/blog/&amp;amp;quot;+article._id.toHexString()}= article.title
%div.body= article.body&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The page that shows a single blog entry:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/views/blog_show-final.html.haml&quot; class=&quot;code-link&quot;&amp;gt;views/blog_show-final.html.haml&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;-# views/blog_show.html.haml
%h1= title
%div.article
%div.created_at= article.created_at
%div.title= article.title
%div.body= article.body
- each comment in article.comments
%div.comment
%div.person= comment.person
%div.comment= comment.comment
%div
%form{ method: 'post', action:&amp;amp;quot;/blog/addComment&amp;amp;quot; }
%input{ type: &amp;amp;quot;hidden&amp;amp;quot;, name:&amp;amp;quot;_id&amp;amp;quot;, value: article._id.toHexString()}
%div
%span Author :
%input{ type: 'text', name: 'person', id: 'addCommentPerson' }
%div
%span Comment :
%textarea{ name: 'comment', rows: 5, id: 'addCommentComment' }
%div#editArticleSubmit
%input{ type: 'submit', value: 'Send' }
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;The stylesheet that renders these pages:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/views/style-final.css.sass&quot; class=&quot;code-link&quot;&amp;gt;views/style-final.css.sass&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;-# views/style.css.sass
body
:font-family &amp;amp;quot;Helvetica Neue&amp;amp;quot;, &amp;amp;quot;Lucida Grande&amp;amp;quot;, &amp;amp;quot;Arial&amp;amp;quot;
:font-size 13px
:text-align center
=text-stroke 1px rgba(255, 255, 255, 0.1)
:color #555
h1, h2
:margin 0
:font-size 22px
:color #343434
h1
:text-shadow 1px 2px 2px #ddd
:font-size 60px
#articles
:text-align left
:margin-left auto
:margin-right auto
:width 320px
.article
:margin 20px
.created_at
:display none
.title
:font-weight bold
:text-decoration underline
:background-color #eee
.body
:background-color #ffa
#article
.created_at
:display none
input[type =text]
:width 490px
:margin-left 16px
input[type =button]
:text-align left
:margin-left 440px
textarea
:width 490px
:height 90px&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;We also need to add a new rule to &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; for serving these view requests:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/app-final.js&quot; class=&quot;code-link&quot;&amp;gt;app-final.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#getBlogs&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;get('/blog/*', function(id){
var self = this;
articleProvider.findById(id, function(error, article) {
self.render('blog_show.html.haml', {
locals: {
title: article.title,
article:article
}
});
});
});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Now if you browse to &amp;lt;a href=&quot;http://localhost:3000&quot;&amp;gt;localhost:3000&amp;lt;/a&amp;gt; the previous articles you added (click &amp;lt;a href=&quot;http://localhost:3000/blog/new&quot;&amp;gt;new post&amp;lt;/a&amp;gt; to create a new one if you have none) should now be visible (apologies for the lack of style once again!) The titles of these articles are now hyperlinks to individual pages that display the article in all itself original glory, comments and all (but alas no comments have been added so far.)&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Comment on an article&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Commenting on an article is a simple extension upon everything we've already gone through, the only minor complexity is in the style of 'update' we use on the back-end.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Transactions are largely non-existent in mongoDB but there are several approaches to achieving atomicity in certain scenarios. For comment addition we're going to use a &amp;lt;code&amp;gt;$push&amp;lt;/code&amp;gt; update that allows us to add an element to the end of an array property of an existing document atomically (which is absolutely perfect for our needs!)&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;All the views/stylesheet changes we need were made in the last set of changes but we need to add in a new route to handle the POST:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/app-final.js&quot; class=&quot;code-link&quot;&amp;gt;app-final.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#addComment&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;
post('/blog/addComment', function() {
var self = this;
articleProvider.addCommentToArticle(this.param('_id'), {
person: self.param('person'),
comment: self.param('comment'),
created_at: new Date()
}, function(error, docs) {
self.redirect('/blog/' + self.param('_id'))
});
});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;and a method to our provider to make the change on the persistent store: &amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;express-mongodb/articleprovider-mongodb-final.js&quot; class=&quot;code-link&quot;&amp;gt;articleprovider-mongodb-final.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#addCommentToArticle&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;
ArticleProvider.prototype.addCommentToArticle = function(articleId, comment, callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback( error );
else {
article_collection.update(
{_id: ObjectID.createFromHexString(articleId)},
{&amp;amp;quot;$push&amp;amp;quot;: {comments: comment}},
function(error, article){
if( error ) callback(error);
else callback(null, article)
});
}
});
};
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;After restarting and browsing to a blog article (any one will do) you should now be able to add comments to your articles ad-infinitum. How easy was that?&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;If you've made it to this point without any issues then congratulations! Otherwise this &amp;lt;a href=&quot;http://github.com/creationix/howtonode.org/tree/master/articles/express-mongodb/express-mongodb-2.zip&quot;&amp;gt;Checkpoint 2&amp;lt;/a&amp;gt; archive should contain all the code as I have it now!&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Where next&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;Clearly this blogging application is very rough and ready (there is no style to speak of for starters) but there are several clear directions that it could take, depending on feedback I'll either leave these as exercises for the reader or provide additional tutorials over time:&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;Markup language support (HTML, Markdown etc. in the posts and comments)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Security, authentication etc.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;An administrative interface&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Multiple blog-support.&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Decent styling &amp;amp;lt;g&amp;amp;gt; (inc. themes)&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;p&amp;gt;I hope this helps at least someone out there get to grips with how you might start actually writing web apps with &amp;lt;a href=&quot;http://nodejs.org&quot;&amp;gt;node&amp;lt;/a&amp;gt;, &amp;lt;a href=&quot;http://github.com/visionmedia/express&quot;&amp;gt;express&amp;lt;/a&amp;gt; and &amp;lt;a href=&quot;http://www.mongodb.org&quot;&amp;gt;mongoDB&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Good luck! :)&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Fin&amp;lt;/strong&amp;gt;.&amp;lt;/p&amp;gt;</description>
<pubDate>Thu Feb 18 2010 21:28:42 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Control Flow in Node Part III</title>
<category></category>
<author>tim@creationix.com (Tim Caswell)</author>
<guid>http://howtonode.org/control-flow-part-iii</guid>
<link/>http://howtonode.org/control-flow-part-iii
<description>&amp;lt;p&amp;gt;While working on my quest to make async programming easier, or at least bearable, I discovered that often in programming you work with a set of data and want to do things on all the items in that set at once.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;This article will explain a way to do async &amp;lt;code&amp;gt;filter&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt; functions where the callback to &amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;filter&amp;lt;/code&amp;gt; is an async operation itself. I will compare the simple task of reading all the files in a directory into memory in both sync and async style programming.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;The Sync Way&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;In a synchronous programming language, this task is very straightforward and can be done in node as long as you understand the consequences. Currently about the only way to program synchronously in node is to use the &amp;lt;code&amp;gt;wait()&amp;lt;/code&amp;gt; method of &amp;lt;a href=&quot;http://nodejs.org/api.html#_tt_events_promise_tt&quot;&amp;gt;promises&amp;lt;/a&amp;gt;. It's not a real sync command, but kinda emulates co-routines/fibers. Using &amp;lt;code&amp;gt;wait&amp;lt;/code&amp;gt; may or may not be deprecated in the near future.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;For this example we will need three methods from the &amp;lt;code&amp;gt;posix&amp;lt;/code&amp;gt; (recently renamed to &amp;lt;code&amp;gt;fs&amp;lt;/code&amp;gt;) package. We need &amp;lt;code&amp;gt;readdir&amp;lt;/code&amp;gt; to get a listing of files in a directory, &amp;lt;code&amp;gt;stat&amp;lt;/code&amp;gt; to test the results (we only want files, not directories), and &amp;lt;code&amp;gt;cat&amp;lt;/code&amp;gt; to read the contents to memory.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;First we'll make a little module that wraps around these three commands and exposes a sync api:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Sync api wrapper around some Posix commands
// Sells it soul to `wait`.
var posix_sync = {
readdir: function (path) {
return Posix.readdir(path).wait();
},
stat: function (filename) {
return Posix.stat(filename).wait();
},
cat: function (filename) {
return Posix.cat(filename).wait();
}
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Then solving the problem is very straightforward using sync style coding:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Here is the sync version:
function loaddir_sync(path) {
return posix_sync.readdir(path).filter(function (filename) {
return posix_sync.stat(filename).isFile();
}).map(function (filename) {
return [filename, posix_sync.cat(filename)];
});
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Since the commands are sync we are able to use the built in &amp;lt;code&amp;gt;filter&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;Array.prototype&amp;lt;/code&amp;gt; on the array returned by &amp;lt;code&amp;gt;posix_sync.readdir&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;This is extremely easy to code, but has dangerous side effects. If these commands were truly sync, then the program would be stopped blocking after every call, waiting for some external IO to finish. Since CPUs are very fast compared to other hardware (like hard-drives), then the cpu sits idle waiting for something else to get back to it.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;As a disclaimer, &amp;lt;code&amp;gt;wait()&amp;lt;/code&amp;gt; in node isn't really synchronous, but it has other deep nasty implications because of the way it works. &amp;lt;a href=&quot;http://groups.google.com/group/nodejs/search?group=nodejs&amp;amp;amp;q=wait&quot;&amp;gt;Search the mailing list&amp;lt;/a&amp;gt; for a history of people who had problems with &amp;lt;code&amp;gt;wait&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Either way, you can't stat one file until the stat for the previous has returned, and you can't read any of the files until all the stats have finished. Obviously this isn't optimal.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;The Async Way&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;They say that in computer science there is always a give and take when comparing different algorithms. The pro to synchronous coding style is that it's very easy to read and write. The con is that it's very inefficient. That's why most programming languages need threads to achieve any level of concurrency, but node is able to do quite a bit on a single threaded platform.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;To make the comparison simple, I'll wrap the &amp;lt;code&amp;gt;posix&amp;lt;/code&amp;gt; library again, but this time in the continuable style. These examples could be written using vanilla promises, but the code would be &amp;lt;a href=&quot;http://github.com/creationix/howtonode.org/blob/master/articles/control-flow-part-iii/program.js#L84&quot;&amp;gt;even longer&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Async api wrapper around some Posix commands
// Uses continuable style for cleaner syntax
var posix = {
readdir: function (path) { return function (next) {
Posix.readdir(path).addCallback(next);
}},
stat: function (filename) { return function (next) {
Posix.stat(filename).addCallback(next);
}},
cat: function (filename) { return function (next) {
Posix.cat(filename).addCallback(next);
}}
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;And an initial implementation of our &amp;lt;code&amp;gt;loaddir&amp;lt;/code&amp;gt; function would be this:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Here is the async version without helpers
function loaddir1(path) { return function (next) {
posix.readdir(path)(function (filenames) {
var realfiles = [];
var count = filenames.length;
filenames.forEach(function (filename) {
posix.stat(filename)(function (stat) {
if (stat.isFile()) {
realfiles.push(filename);
}
count--;
if (count &amp;amp;lt;=0) {
var results = [];
realfiles.forEach(function (filename) {
posix.cat(filename)(function (data) {
results.push([filename, data]);
if (results.length === realfiles.length) {
next(results);
}
});
});
}
});
});
});
}}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Yikes! That is almost four times as long and indented several times deeper. I know it's a trade-off, but at this point I'm thinking I'll return to &amp;lt;a href=&quot;http://www.ruby-lang.org/&quot;&amp;gt;Ruby&amp;lt;/a&amp;gt; with &amp;lt;a href=&quot;http://unicorn.bogomips.org/&quot;&amp;gt;clusters of servers&amp;lt;/a&amp;gt; on the backend to handle concurrency.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Map and Filter Helpers for Async Code&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Since map and filter are common tasks in programming and that's what we really want here, let's write some helpers to make this beast of code a little smaller:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Both of these take an array and an async callback. When all callbacks
// have returned, it sends the output to `next`
function map(array, callback) { return function (next) {
var counter = array.length;
var new_array = [];
array.forEach(function (item, index) {
callback(item, function (result) {
new_array[index] = result;
counter--;
if (counter &amp;amp;lt;= 0) {
new_array.length = array.length
next(new_array);
}
});
});
}}
function filter(array, callback) { return function (next) {
var counter = array.length;
var valid = {};
array.forEach(function (item, index) {
callback(item, function (result) {
valid[index] = result;
counter--;
if (counter &amp;amp;lt;= 0) {
var result = [];
array.forEach(function (item, index) {
if (valid[index]) {
result.push(item);
}
});
next(result);
}
});
});
}}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Now with our helpers, let's try the async version again to see how much shorter we can make it:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Here is the async version with filter and map helpers:
function loaddir2(path) { return function (next) {
posix.readdir(path)(function (filenames) {
filter(filenames, function (filename, callback) {
posix.stat(filename)(function (stat) {
callback(stat.isFile());
});
})(function (filenames) {
map(filenames, function (filename, callback) {
posix.cat(filename)(function (data) {
callback([filename, data]);
});
})(next);
});
});
}}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;That code is much shorter and easier to read. Also, now that the code is executing in parallel, we can issue a stat call for all the files in a directory at once and then collect the results as they come in. But with this version, not a single &amp;lt;code&amp;gt;cat&amp;lt;/code&amp;gt; can execute until all the &amp;lt;code&amp;gt;stat&amp;lt;/code&amp;gt; calls finish. In an ideal world, the program would start reading the file as soon as it knows it's a file and not a directory.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Combined Filter and Map Helper&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;Often you will want to filter and then map on the same data set. Let's make a combined &amp;lt;code&amp;gt;filter_map&amp;lt;/code&amp;gt; helper and see how it helps:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;function filter_map(array, callback) { return function (next) {
var counter = array.length;
var new_array = [];
array.forEach(function (item, index) {
callback(item, function (result) {
new_array[index] = result;
counter--;
if (counter &amp;amp;lt;= 0) {
new_array.length = array.length;
next(new_array.filter(function (item) {
return typeof item !== 'undefined';
}));
}
});
});
}}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;I found it neat that this combined helper is about as small as the smaller of the two separate helpers. That is very cool!&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Now with this combined helper, let's write a truly parallel &amp;lt;code&amp;gt;loaddir&amp;lt;/code&amp;gt; function:&amp;lt;/p&amp;gt;
&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;// Here is the async version with a combined filter and map helper:
function loaddir3(path) { return function (next) {
posix.readdir(path)(function (filenames) {
filter_map(filenames, function (filename, callback) {
posix.stat(filename)(function (stat) {
if (stat.isFile()) {
posix.cat(filename)(function (data) {
callback([filename, data]);
});
} else {
callback();
}
});
})(next);
});
}}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&amp;lt;p&amp;gt;Here we will issue all the &amp;lt;code&amp;gt;stat&amp;lt;/code&amp;gt; commands at once, and as they come back, check to see if it's a file and if so, then fire off the &amp;lt;code&amp;gt;cat&amp;lt;/code&amp;gt; command right away. If not we'll output the result of &amp;lt;code&amp;gt;undefined&amp;lt;/code&amp;gt; signifying to &amp;lt;code&amp;gt;filter_map&amp;lt;/code&amp;gt; that we're not interested in that entry. When the &amp;lt;code&amp;gt;cat&amp;lt;/code&amp;gt; command comes back we'll send the file contents to the helper. When all the items have either sent &amp;lt;code&amp;gt;undefined&amp;lt;/code&amp;gt; or some text, then the helper knows it's done and gives us the result.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;Conclusion and Source Code&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;While it is a tradeoff in code complexity vs performance, with a little thinking and some good libraries, we can make async programming manageable enough to be understandable while taking full advantage of the parallel nature of non-blocking IO in node.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Full runnable source code can be found on &amp;lt;a href=&quot;http://github.com/creationix/howtonode.org/tree/master/articles/control-flow-part-iii/&quot;&amp;gt;github&amp;lt;/a&amp;gt;. These examples were tested on node version &amp;lt;code&amp;gt;v0.1.28-68-gdc01587&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;</description>
<pubDate>Mon Feb 15 2010 15:21:11 GMT+0000 (UTC)</pubDate>
</item>
<item>
<title>Prototypal Inheritance</title>
<category></category>
<author>tim@creationix.com (Tim Caswell)</author>
<guid>http://howtonode.org/prototypical-inheritance</guid>
<link/>http://howtonode.org/prototypical-inheritance
<description>&amp;lt;p&amp;gt;In almost all modern programming languages we use the concept of Object Oriented Programming (OOP) to help manage the complexity of today's software. The biggest challenge in modern software is in fact managing the complexity of it.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Most languages do this with a variant OOP called Classical OOP. This is the one you see in Java, C#, C++, PHP, Ruby, and Python. It has the idea that classes should be separate from instances. Classes hold behavior and instances hold data.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;While this is a great abstraction, I would like to experiment with other ideas. Prototypal inheritance gets rid of the distinction between class and instance, between constructor and method. It's just objects with inherited and local properties.&amp;lt;/p&amp;gt;
&amp;lt;h2&amp;gt;So what does JavaScript have?&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;From what I hear (I wasn't there at the time), JavaScript was initially a prototypal inheritance system. It was super simple like the rest of the language. But then Netscape decided to make it be more like Java and added the idea of constructors to the language. Hence pseudo classes were born.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Classical OOP&amp;lt;/h3&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;prototypal-inheritance/classical.js&quot; class=&quot;code-link&quot;&amp;gt;classical.js&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;function Person(name) {
this.name = name
}
Person.prototype = {
greet: function () {
return &amp;amp;quot;Hello world, my name is &amp;amp;quot; + this.name;
}
};
var frank = new Person(&amp;amp;quot;Frank Dijon&amp;amp;quot;);
frank.greet();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 'Hello world, my name is Frank Dijon'&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Here we have a class like object &amp;lt;code&amp;gt;Person&amp;lt;/code&amp;gt;. Actually it's just a regular JavaScript function, but that's how it works, there are no real classes. There are many ways to emulate classical OOP, but the most straightforward and the one designed into the language is this pattern. Only functions can have prototypes and prototypes hold instance methods. Then instances are &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; instances of the function which is now dubbed a constructor.&amp;lt;/p&amp;gt;
&amp;lt;h3&amp;gt;Prototypal OOP&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;I don't like the &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; keyword, it overloads the meaning of functions and is dangerous. If we were to say &amp;lt;code&amp;gt;frank = Person(&quot;Frank&quot;)&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; inside the function would now be the global &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; object, not the new instance! The constructor would be overriding all sorts of global variables inadvertently. Also bad things happen if you &amp;lt;code&amp;gt;return&amp;lt;/code&amp;gt; from a constructor function.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Instead try this on for size:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;prototypal-inheritance/prototypal.js&quot; class=&quot;code-link&quot;&amp;gt;prototypal.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#intro-to-style&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var Person = {
greet: function () {
return &amp;amp;quot;Hello world, my name is &amp;amp;quot; + this.name;
}
};
var frank = Object.create(Person);
frank.name = &amp;amp;quot;Frank Dijon&amp;amp;quot;;
frank.greet();
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; 'Hello world, my name is Frank Dijon'&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;Object.create&amp;lt;/code&amp;gt; is new to JavaScript (it's part of &amp;lt;a href=&quot;http://www.ecma-international.org/publications/standards/Ecma-262.htm&quot;&amp;gt;ES5&amp;lt;/a&amp;gt;), but &amp;lt;a href=&quot;http://wiki.github.com/ry/node/ecma-5mozilla-features-implemented-in-v8&quot;&amp;gt;node supports it&amp;lt;/a&amp;gt; so we can safely use it. This creates a new object that inherits from another object. &amp;lt;code&amp;gt;Object.create&amp;lt;/code&amp;gt; actually can set properties right away, but the syntax is rather verbose:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;prototypal-inheritance/prototypal.js&quot; class=&quot;code-link&quot;&amp;gt;prototypal.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#object-create&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;Object.create(Person, {name: {value: &amp;amp;quot;Frank Dijon&amp;amp;quot;, enumerable: true}})
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; { name: 'Frank Dijon' }&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;There is more you can set, but &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;enumerable&amp;lt;/code&amp;gt; are the interesting ones. What &amp;lt;code&amp;gt;enumerable&amp;lt;/code&amp;gt; does is tell operators like &amp;lt;code&amp;gt;for ... in&amp;lt;/code&amp;gt; if they should enumerate over that key. When you set a property directly, it's enumerable property is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; automatically. &amp;lt;code&amp;gt;Object.create&amp;lt;/code&amp;gt; actually defaults to false, so we could write this as:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;prototypal-inheritance/prototypal.js&quot; class=&quot;code-link&quot;&amp;gt;prototypal.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#object-create-ii&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;Object.create(Person, {name: {value: &amp;amp;quot;Frank Dijon&amp;amp;quot;}});
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; {}&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Just make sure you understand that most functions like &amp;lt;code&amp;gt;sys.inspect&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;JSON.stringify&amp;lt;/code&amp;gt; won't show the name property of frank now that it's hidden. If you pass &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; as the second argument to &amp;lt;code&amp;gt;sys.inspect&amp;lt;/code&amp;gt;, it will show hidden properties using &amp;lt;code&amp;gt;Object.getOwnPropertyNames&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;prototypal-inheritance/prototypal.js&quot; class=&quot;code-link&quot;&amp;gt;prototypal.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#object-create-iii&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var frank = Object.create(Person, {name: {value: &amp;amp;quot;Frank Dijon&amp;amp;quot;}})
sys.puts(sys.inspect(frank));
sys.puts(sys.inspect(frank, true));
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;{}
{ [name]: 'Frank Dijon' }
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;h2&amp;gt;Using &amp;lt;code&amp;gt;Object.spawn&amp;lt;/code&amp;gt;&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;While Object.create is nice, it's still too verbose for my taste. On my projects I made a new function called &amp;lt;code&amp;gt;Object.spawn&amp;lt;/code&amp;gt;. Here is the source for reference:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;prototypal-inheritance/spawn.js&quot; class=&quot;code-link&quot;&amp;gt;spawn.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#object-spawn&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;Object.spawn = function (parent, props) {
var defs = {}, key;
for (key in props) {
if (props.hasOwnProperty(key)) {
defs[key] = {value: props[key], enumerable: true};
}
}
return Object.create(parent, defs);
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;div class=&quot;last-expression&quot;&amp;gt;=&amp;amp;gt; [Function]&amp;lt;/div&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;Then you can create hierarchies of objects easily:&amp;lt;/p&amp;gt;
&amp;lt;div class=&quot;snippet&quot;&amp;gt;&amp;lt;a href=&quot;prototypal-inheritance/spawn.js&quot; class=&quot;code-link&quot;&amp;gt;spawn.js&amp;lt;span class=&quot;hash&quot;&amp;gt;#animals&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;var Animal = {
eyes: 2,
legs: 4,
name: &amp;amp;quot;Animal&amp;amp;quot;,
toString: function () {
return this.name + &amp;amp;quot; with &amp;amp;quot; +
this.eyes + &amp;amp;quot; eyes and &amp;amp;quot; +
this.legs + &amp;amp;quot; legs.&amp;amp;quot;;
}
}
var Dog = Object.spawn(Animal, {
name: &amp;amp;quot;Dog&amp;amp;quot;
});
var Insect = Object.spawn(Animal, {
name: &amp;amp;quot;Insect&amp;amp;quot;,
legs: 6
});
var fred = Object.spawn(Dog);
var pete = Object.spawn(Insect);
sys.puts(fred);
sys.puts(pete);
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;dl class=&quot;output&quot;&amp;gt;&amp;lt;dt&amp;gt;Output&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;Dog with 2 eyes and 4 legs.
Insect with 2 eyes and 6 legs.
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;/div&amp;<