<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Sergio Pereira</title><subtitle type="html">There are no half-solutions because there isn&amp;#39;t half a problem</subtitle><id>http://devlicio.us/blogs/sergio_pereira/atom.aspx</id><link rel="alternate" type="text/html" href="http://devlicio.us/blogs/sergio_pereira/default.aspx" /><link rel="self" type="application/atom+xml" href="http://devlicio.us/blogs/sergio_pereira/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2009-11-04T18:33:00Z</updated><entry><title>dotTrace 3.1 64-bit disabled inside Visual Studio 2008</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/03/12/dottrace-3-1-64-bit-disabled-inside-visual-studio-2008.aspx" /><id>/blogs/sergio_pereira/archive/2010/03/12/dottrace-3-1-64-bit-disabled-inside-visual-studio-2008.aspx</id><published>2010-03-12T18:15:00Z</published><updated>2010-03-12T18:15:00Z</updated><content type="html">&lt;p&gt;
I work on a web application and I use &lt;a href="http://www.jetbrains.com/profiler/"&gt;dotTrace&lt;/a&gt; 
when some profiling is needed. The problem is that I cannot fire off doTrace directly from inside Visual
Studio 2008 because the commands and toolbar icons to launch it are permanently disabled. Well, not anymore.
&lt;/p&gt;

&lt;h3&gt;Background&lt;/h3&gt;
&lt;p&gt;
The web application I work on is a 64-bit application. I use a 64-bit version of Windows (namely, Win2008 x64).
I installed the 64-bit version of dotTrace 3.1 and it does work stand-alone but it never worked integrated with
VS 2008, which is a shame because it contains some neat features like it&amp;#39;s enabling the ReSharper test runner
to run the chosen test(s) directly under dotTrace profiling. The screen shot below shows how it should look like
but on my box these dotTrace commands were simply disabled.
&lt;/p&gt;

&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.03/dottrace_2D00_64.png" alt="" /&gt;&lt;/p&gt;

&lt;h3&gt;The fix&lt;/h3&gt;
&lt;p&gt;
After much disappointment with the missing features, my fellow &lt;a href="http://devlicio.us/"&gt;Devlicio.us&lt;/a&gt;
blogger &lt;a href="http://devlicio.us/blogs/hadi_hariri/"&gt;Hadi Hariri&lt;/a&gt; put me in contact with 
&lt;a href="http://blogs.jetbrains.com/nocturne/"&gt;Oleg Stepanov&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
The first suggestion was trying the 32-bit version of dotTrace, which wasn&amp;#39;t an option for
me because, as I said, my application and all the supporting utilities are 64-bit, 
it runs under a 64-bit process, so that&amp;#39;s ultimately how I need to profile it.
&lt;/p&gt;

&lt;p&gt;
Then Oleg explained that the problem is that VS is a 32-bit application and it
was looking for a registry key in the wrong place, not finding it, and then
it was assuming dotTrace wasn&amp;#39;t available.
&lt;/p&gt;

&lt;p&gt;
 Hmmm... That sounded 
 &lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/07/20/resharper-test-runner-in-64-bit-windows.aspx"&gt;eerily familiar&lt;/a&gt;, didn&amp;#39;t it? Once again the little annoyances of developing 64-bit code with
 32-bit tools come to bite us.
&lt;/p&gt;

&lt;p&gt;
To fix the problem, just like 
&lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/07/20/resharper-test-runner-in-64-bit-windows.aspx"&gt;the other time it happened&lt;/a&gt;, we just need to copy the right registry key to its
corresponding place under the Wow6432Node key. 
&lt;/p&gt;

&lt;p&gt;
Open the Registry Editor and go to the
&lt;code&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\&lt;/code&gt; key.
One of its GUID-named subkeys will contain the dotTrace information. Just search for dotTrace 
and find the right subkey. Now just copy (or export/edit/import) that key under 
&lt;code&gt;HKEY_LOCAL_MACHINE\SOFTWARE\&lt;b&gt;&lt;u&gt;Wow6432Node&lt;/u&gt;&lt;/b&gt;\Microsoft\Windows\CurrentVersion\Uninstall\&lt;/code&gt;
and you&amp;#39;re ready to restart Visual Studio and see all the integrated dotTrace features
come alive.
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55898" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author></entry><entry><title>[ANN] Chicago ALT.NET shows Rake and Albacore</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/03/09/ann-chicago-alt-net-shows-rake-and-albacore.aspx" /><id>/blogs/sergio_pereira/archive/2010/03/09/ann-chicago-alt-net-shows-rake-and-albacore.aspx</id><published>2010-03-09T23:35:00Z</published><updated>2010-03-09T23:35:00Z</updated><content type="html">&lt;p&gt;
I haven&amp;#39;t mentioned our meetings here in a while but our group has been going strong and enthusiastic all this time.
&lt;/p&gt;

&lt;p&gt;
Tomorrow, March 10&lt;sup&gt;th&lt;/sup&gt; our topic will be build scripts for .Net projects using Rake and Albacore. I&amp;#39;ve been 
using Rake and a little bit of Albacore in my own projects and I&amp;#39;m ready to say that it will take a very serious 
event to make me go back to NAnt or MSBuild.
&lt;/p&gt;

&lt;h3&gt;Introduction to Rake with Albacore.NET&lt;/h3&gt;
&lt;p&gt;
		&lt;span style="font-size:x-small;"&gt;6:00 pm&lt;/span&gt; 
		&lt;br /&gt;

		Pizza and networking time
&lt;/p&gt;
&lt;p&gt;
		&lt;span style="font-size:x-small;"&gt;6:30 pm&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
	How would you to write your build &lt;em&gt;scripts&lt;/em&gt; using a
	&lt;em&gt;scripting&lt;/em&gt; language instead of XML? In this month&amp;#39;s meeting
	we will see how the ease of programming in Ruby can be used
	to create a much more pleasant and extensible build script.

&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt; isn&amp;#39;t just for Rubyists or 
Alphageeks anymore. &lt;a href="http://albacorebuild.net/"&gt;Albacore&lt;/a&gt; helps bring 
the power and expresiveness of the Ruby language to the world of .NET build 
automation. Using Rake it&amp;#39;s never been easier to handle build automation, 
test execution, continuous integration and just about any task you need to 
automate for your build.&lt;/p&gt;
&lt;p&gt;
&lt;img style="margin-right:5px;" src="http://chicagoalt.net/content/images/events/michael-d-hall.jpg" alt="" align="left" /&gt;
&lt;a href="http://www.just3ws.com/%20"&gt;Michael D. Hall&lt;/a&gt; has been developing software 
on the Microsoft platform for over a decade. He&amp;#39;s been an Alt.NETter for years 
and is really enjoying the exposure to different ideas and concepts beyond the 
safe confines of the .NET world. Currently he&amp;#39;s a consultant working with Obtiva 
and has started a &lt;a href="http://www.clouddevelopersgroup.com/"&gt;Cloud Developer&amp;#39;s Group&lt;/a&gt; 
that meets monthly in McHenry county.&lt;/p&gt;

&lt;a href="http://altnetchicago.eventbrite.com" target="_blank"&gt;&lt;img border="0" src="http://www.eventbrite.com/registerbutton?eid=588872333" alt="Register for Introduction to Rake with Albacore.NET in Chicago, IL  on Eventbrite" /&gt;&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55811" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="Ruby" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Ruby/default.aspx" /><category term="Automation" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Automation/default.aspx" /><category term="alt.net" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/alt.net/default.aspx" /><category term="Announcement" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Announcement/default.aspx" /><category term="Community" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Community/default.aspx" /></entry><entry><title>Rule "Previous releases of Microsoft Visual Studio 2008" failed</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/03/07/rule-quot-previous-releases-of-microsoft-visual-studio-2008-quot-failed.aspx" /><id>/blogs/sergio_pereira/archive/2010/03/07/rule-quot-previous-releases-of-microsoft-visual-studio-2008-quot-failed.aspx</id><published>2010-03-07T10:43:00Z</published><updated>2010-03-07T10:43:00Z</updated><content type="html">&lt;p&gt;
 Today I was trying to install SQL 2008 on my box and the setup stopped after checking a bunch of
rules. The error message was the title of this post.
&lt;/p&gt;

&lt;p&gt;
A quick search on the internet revealed that somehow the installer didn&amp;#39;t believe I had VS 2008 &lt;b&gt;SP1&lt;/b&gt;
installed, which I did. The recommendations in &lt;a href="http://support.microsoft.com/kb/956139"&gt;the KB article&lt;/a&gt;
were kind of insulting. There&amp;#39;s no way I&amp;#39;d spend hours of my day uninstalling and reinstalling VS and SQL &amp;mdash; sorry, no chance. I
also could not accept not installing the Management Tools, for example. I also did not have any Express version of VS or SQL installed in this box.
&lt;/p&gt;

&lt;p&gt;
A little snooping around with &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx"&gt;ProcMon&lt;/a&gt;
led me to the following registry key: 
&lt;/p&gt;

&lt;pre&gt;HKLM\SOFTWARE\Wow6432Node\Microsoft\DevDiv\VS\Servicing\9.0\IDE\1033&lt;/pre&gt;

&lt;p&gt;
In that key I noticed the suspicious values:
&lt;/p&gt;

&lt;pre&gt;&amp;quot;SP&amp;quot;=dword:00000000
&amp;quot;SPIndex&amp;quot;=dword:00000000
&amp;quot;SPName&amp;quot;=&amp;quot;RTM&amp;quot;
&lt;/pre&gt;

&lt;p&gt;
Without quitting the SQL server installer validaton screen, I changed these values to what you see below, crossed my fingers 
and rerun the installer validation, &lt;b&gt;which passed!&lt;/b&gt;
&lt;/p&gt;

&lt;pre&gt;&amp;quot;SP&amp;quot;=dword:00000001
&amp;quot;SPIndex&amp;quot;=dword:00000001
&amp;quot;SPName&amp;quot;=&amp;quot;SP1&amp;quot;
&lt;/pre&gt;

&lt;p&gt;
Now, I didn&amp;#39;t really guess those values. I looked in a sibling registry key (...Servicing\9.0\IDE\1033) and saw
that it contained those new values, then I copied them. 
&lt;/p&gt;

&lt;p&gt;
I think I didn&amp;#39;t break anything. So far all seems to be working. But, as usual with anything related
to manual registry hacking, you have to be really insane to change your settings because you
read on a random blog on the &amp;#39;net. I&amp;#39;m just saying... Don&amp;#39;t come crying if your house burns down because of this.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55695" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="Tips-and-Tricks" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx" /><category term="SQLServer" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/SQLServer/default.aspx" /></entry><entry><title>jQuery Custom Element and Global Events</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/02/21/jquery-custom-element-and-global-events.aspx" /><id>/blogs/sergio_pereira/archive/2010/02/21/jquery-custom-element-and-global-events.aspx</id><published>2010-02-21T18:09:00Z</published><updated>2010-02-21T18:09:00Z</updated><content type="html">&lt;p&gt;This last week I learned a new thing about jQuery custom events, particularly the ones of global nature.
There&amp;#39;s good &lt;a href="http://api.jquery.com/trigger/"&gt;documentation&lt;/a&gt; 
and examples about custom element events, but
not much for the &lt;i&gt;global&lt;/i&gt; ones.&lt;/p&gt;

&lt;h3&gt;Why do we need custom events?&lt;/h3&gt;

&lt;p&gt;Custom events make it easier to keep complex pages under control. They
are a pillar for loosely-coupled UI scripts. Let&amp;#39;s start with a
simple example.&lt;/p&gt;

&lt;p&gt;Suppose we have a fairly complex and dynamic page where many elements
are Ajax-editable, using in-place editors or any other approach that 
posts updates to the server. Depending on how quickly the server 
responds to the request, there&amp;#39;s a chance the user can start another
simultaneous request before the first one finishes, maybe even seeing
inconsistent results, by clicking a button too soon.&lt;/p&gt;

&lt;p&gt;In our example &amp;mdash; a fraction of what a real complex page would be &amp;mdash; 
what we want to do is disable some of these buttons while
the data is being changed, and re-enable them once we hear back from the server.&lt;/p&gt;

&lt;pre name="code" class="html:nogutter"&gt;Click the field to edit it:&amp;lt;br&amp;gt;

&amp;lt;input type=&amp;quot;text&amp;quot; readonly=&amp;quot;readonly&amp;quot; id=&amp;quot;email&amp;quot; name=&amp;quot;email&amp;quot;
   value=&amp;quot;joe@doe.com&amp;quot; style=&amp;quot;background-color: #eee;&amp;quot;/&amp;gt; 

&amp;lt;input type=&amp;quot;button&amp;quot; class=&amp;quot;userOperation&amp;quot; id=&amp;quot;sendButton&amp;quot; value=&amp;quot;Send Message&amp;quot;&amp;gt;
&amp;lt;input type=&amp;quot;button&amp;quot; class=&amp;quot;userOperation&amp;quot; id=&amp;quot;summaryButton&amp;quot; value=&amp;quot;Summary&amp;quot;&amp;gt;&lt;/pre&gt;

&lt;h3&gt;Custom Element Events&lt;/h3&gt;

&lt;p&gt;Let&amp;#39;s tackle this problem first with the custom element events. Below is a 
summary of how these custom events are used.&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;$(&amp;#39;#publisher&amp;#39;).trigger(&amp;#39;eventName&amp;#39;);

$(&amp;#39;#publisher1&amp;#39;).bind(&amp;#39;eventName&amp;#39;, function() {
   //eventName happened. React here.
   $(&amp;#39;#subscriber1&amp;#39;).doStuff();
   $(&amp;#39;#subscriber2&amp;#39;).doOtherStuff();
   // more...
});&lt;/pre&gt;

&lt;p&gt;In this case we will make the elements being edited announce that they entered edit mode
so that any other element can act on that announcement.&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;$(&amp;#39;#email&amp;#39;).
click(function(){
	$(this).removeAttr(&amp;#39;readonly&amp;#39;).css({backgroundColor: &amp;#39;&amp;#39;});
	$(this).trigger(&amp;#39;editStart&amp;#39;);
}).
blur(function(){
	$(this).attr(&amp;#39;readonly&amp;#39;, &amp;#39;readonly&amp;#39;).css({backgroundColor: &amp;#39;#eee&amp;#39;});
	$.post(&amp;#39;/updateEmail&amp;#39;, $(&amp;#39;#email&amp;#39;).serialize(), function() {
		$(this).trigger(&amp;#39;editComplete&amp;#39;);
	});
}).
bind(&amp;#39;editStart&amp;#39;, function(){
	// &amp;quot;this&amp;quot; is the #email element
	console.log(&amp;#39;edit started, this =  &amp;#39; + this.id);
	$(&amp;#39;.userOperation&amp;#39;).attr(&amp;#39;disabled&amp;#39;, &amp;#39;disabled&amp;#39;);
}).
bind(&amp;#39;editComplete&amp;#39;, function(){
	// &amp;quot;this&amp;quot; is the #email element
	console.log(&amp;#39;edit complete, this =  &amp;#39; + this.id);
	$(&amp;#39;.userOperation&amp;#39;).removeAttr(&amp;#39;disabled&amp;#39;);		
});

$(&amp;#39;#sendButton&amp;#39;).click(function(){
	//code to send a message
	alert(&amp;#39;Message sent&amp;#39;);
});

$(&amp;#39;#summaryButton&amp;#39;).click(function(){
	//code to generate summary
	alert(&amp;#39;Summary created&amp;#39;);
});&lt;/pre&gt;


&lt;p&gt;This approach works well in the beginning but gets really ugly as
more elements need to publish their own similar events or when
other new elements need to do somethings with these events too. We
will need to bind handlers to all these element&amp;#39;s events and the code 
inside these handlers will start getting longer and probably too
far from the rest of the code that relates to it.&lt;/p&gt;

&lt;h3&gt;One step forward with page level events&lt;/h3&gt;

&lt;p&gt;Since the events we are producing here really reflect the document
state more than any individual field&amp;#39;s state, let&amp;#39;s move that event
to a more top level element, namely the &lt;code&gt;body&lt;/code&gt; element:&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;$(&amp;#39;#email&amp;#39;).
click(function(){
	$(this).removeAttr(&amp;#39;readonly&amp;#39;).css({backgroundColor: &amp;#39;&amp;#39;});
	$(&amp;#39;body&amp;#39;).trigger(&amp;#39;editStart&amp;#39;);
}).
blur(function(){
	$(this).attr(&amp;#39;readonly&amp;#39;, &amp;#39;readonly&amp;#39;).css({backgroundColor: &amp;#39;#eee&amp;#39;});
	$.post(&amp;#39;/updateEmail&amp;#39;, $(&amp;#39;#email&amp;#39;).serialize(), function() {
		$(&amp;#39;body&amp;#39;).trigger(&amp;#39;editComplete&amp;#39;);
	});
});

$(&amp;#39;body&amp;#39;).
bind(&amp;#39;editStart&amp;#39;, function(){
	// &amp;quot;this&amp;quot; is the body element
	console.log(&amp;#39;edit started, this =  &amp;#39; + this.tagName);
	$(&amp;#39;.userOperation&amp;#39;).attr(&amp;#39;disabled&amp;#39;, &amp;#39;disabled&amp;#39;);
}).
bind(&amp;#39;editComplete&amp;#39;, function(){
	// &amp;quot;this&amp;quot; is the body element
	console.log(&amp;#39;edit complete, this =  &amp;#39; + this.tagName);
	$(&amp;#39;.userOperation&amp;#39;).removeAttr(&amp;#39;disabled&amp;#39;);		
});

$(&amp;#39;#sendButton&amp;#39;).click(function(){
	//code to send a message
	alert(&amp;#39;Message sent&amp;#39;);
});

$(&amp;#39;#summaryButton&amp;#39;).click(function(){
	//code to generate summary
	alert(&amp;#39;Summary created&amp;#39;);
});&lt;/pre&gt;


&lt;p&gt;Now we&amp;#39;re getting somewhere. We reduced the number of event sources to
just one, so guaranteed less duplication. But it still has some shortcomings.&lt;/p&gt;

&lt;p&gt;The code is still bound to a different element than the one we want to operate on.
What I mean by that is that the event handlers are in the context of the elements
publishing the event and the code in the handlers is typically geared towards the
elements that need to react to that event, that is, the &lt;code&gt;this&lt;/code&gt; keyword
is less useful than in most of your common event handlers.&lt;/p&gt;

&lt;p&gt;The pattern of these page-level events is:&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;$(&amp;#39;body&amp;#39;).trigger(&amp;#39;eventName&amp;#39;);

$(&amp;#39;body&amp;#39;).bind(&amp;#39;eventName&amp;#39;, function() {
   //eventName happened. React here.
   $(&amp;#39;#subscriber1&amp;#39;).doStuff();
   $(&amp;#39;#subscriber2&amp;#39;).doOtherStuff();
   // more...
});&lt;/pre&gt;


&lt;h3&gt;But wait, jQuery has real global events too&lt;/h3&gt;

&lt;p&gt;I had settled down with using the above style of global events until
someone at work pointed out that there&amp;#39;s another way of doing this, which
unfortunately isn&amp;#39;t as well discussed: the &lt;b&gt;custom global events&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s our code using global custom events:&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;$(&amp;#39;#email&amp;#39;).click(function(){
	$(this).removeAttr(&amp;#39;readonly&amp;#39;).css({backgroundColor: &amp;#39;&amp;#39;});
	$.event.trigger(&amp;#39;editStart&amp;#39;);
}).blur(function(){
	$(this).attr(&amp;#39;readonly&amp;#39;, &amp;#39;readonly&amp;#39;).css({backgroundColor: &amp;#39;#eee&amp;#39;});
	$.post(&amp;#39;/updateEmail&amp;#39;, $(&amp;#39;#email&amp;#39;).serialize(), function() {
		$.event.trigger(&amp;#39;editComplete&amp;#39;);
	});
});

$(&amp;#39;.userOperation&amp;#39;).bind(&amp;#39;editStart&amp;#39;, function(){
	// &amp;quot;this&amp;quot; is a .userOperation button
	console.log(&amp;#39;edit started, button: &amp;#39; + this.id);
	$(&amp;#39;.userOperation&amp;#39;).attr(&amp;#39;disabled&amp;#39;, &amp;#39;disabled&amp;#39;);
}).bind(&amp;#39;editComplete&amp;#39;, function(){
	// &amp;quot;this&amp;quot; is a .userOperation button
	console.log(&amp;#39;edit complete, button: &amp;#39; + this.id);
	$(&amp;#39;.userOperation&amp;#39;).removeAttr(&amp;#39;disabled&amp;#39;);		
});

$(&amp;#39;#sendButton&amp;#39;).click(function(){
	//code to send a message
	alert(&amp;#39;Message sent&amp;#39;);
});

$(&amp;#39;#summaryButton&amp;#39;).click(function(){
	//code to generate summary
	alert(&amp;#39;Summary created&amp;#39;);
});&lt;/pre&gt;


&lt;p&gt;What is great about this type of event is that they are in the context
of the subscribing elements, as if these elements were the publishers of
the event, much like the majority of the event handling code we write.&lt;/p&gt;

&lt;p&gt;They also allow us to move more code next to the other event handler for
the subscribing elements, and even chain them all together. As an example,
let&amp;#39;s modify the event handlers of the &lt;code&gt;#sendButton&lt;/code&gt; element
to add some different behavior when the &lt;i&gt;editStart&lt;/i&gt; event happens.&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;$(&amp;#39;#sendButton&amp;#39;).click(function(){
	//code to send a message
	alert(&amp;#39;Message sent&amp;#39;);
}).bind(&amp;#39;editStart&amp;#39;, function(){
	// &amp;quot;this&amp;quot; is the #sendButton button
	this.value = &amp;#39;Send message (please refresh)&amp;#39;;
	// change the click event handler.
	$(this).unbind(&amp;#39;click&amp;#39;).click(function(){
		alert(&amp;#39;Sorry, refresh page before sending message&amp;#39;);
	});
});&lt;/pre&gt;

&lt;p&gt;And here is the simplified representation of the global events code.&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;$.event.trigger(&amp;#39;eventName&amp;#39;);

$(&amp;#39;#subscriber1&amp;#39;).bind(&amp;#39;eventName&amp;#39;, function() {
   //eventName happened. React here.
   $(this).doStuff();
});

$(&amp;#39;#subscriber2&amp;#39;).bind(&amp;#39;eventName&amp;#39;, function() {
   //eventName happened. React here.
   $(this).doOtherStuff();
});
//more...&lt;/pre&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Event-based programming is the usual way we write UI code. By understanding 
the different types of events that jQuery provides we can allow
our UI to grow without getting into a messy nightmare of 
event handling code scattered all over the place.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55475" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="JavaScript" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx" /><category term="jQuery" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/jQuery/default.aspx" /></entry><entry><title>Code coverage reports with NCover and MSBuild</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/02/09/code-coverage-reports-with-ncover-and-msbuild.aspx" /><id>/blogs/sergio_pereira/archive/2010/02/09/code-coverage-reports-with-ncover-and-msbuild.aspx</id><published>2010-02-09T18:11:00Z</published><updated>2010-02-09T18:11:00Z</updated><content type="html">&lt;p&gt;
I&amp;#39;ve been doing a lot of static analysis on our projects at work lately. As 
part of that task we added &lt;a href="http://www.ncover.com/"&gt;NCover&lt;/a&gt; to our automated build process. Our
build runs on Team Build (TFS) and is specified in an MSBuild file.

&lt;/p&gt;
&lt;p&gt;
We wanted to take code metrics very seriously and we purchased the 
complete version of the product to take full advantage of its 
capabilities.

&lt;/p&gt;
&lt;p&gt;
Getting NCover to run in your build is very simple and the online 
documentation will be enough to figure it out. The problem comes
when you begin needing to create more and more variations of the
reports. The online documentation is a little short on this aspect,
especially on how to use the MSBuild or NAnt custom tasks. I hear
they plan to update the site with better docs for the next version 
of the product.

&lt;/p&gt;
&lt;p&gt;
NCover Complete comes with 23 different types of reports and 
a ton of parameters that can be configured to produce far
more helpful reports than just sticking to the defaults.

&lt;/p&gt;
&lt;p&gt;
For example, we are working on a new release of our product and
we are pushing ourselves to produce more testable code and
write more unit tests for all the new code. The problem is
that the new code is a just tiny fraction of the existing code and
the metrics get averaged down by the older code.

&lt;/p&gt;
&lt;p&gt;
The key is to separate the code coverage profiling (which is
done by NCover while it runs all the unit tests with NUnit) from
the rendering of the reports. That way we only run the code coverage once; and that
can sometimes take a good chunk of time to produce the coverage data. 
Rendering the reports is much quicker since the NCover reporting engine can feed off the
coverage data as many times as we need, very quickly.

&lt;/p&gt;
&lt;p&gt;
Once we have the coverage data we can choose which report types we want 
to create, the thresholds for sufficient coverage (or to fail the build), which assemblies/types/methods
we want to include/exclude from each report and where to save each of them.

&lt;h3&gt;Example&lt;/h3&gt;

&lt;p&gt;
To demonstrate what I just described in practice, I decided to take
an existing open source project and add NCover reporting to it. The
project I selected was &lt;a href="http://www.codeplex.com/AutoMapper"&gt;AutoMapper&lt;/a&gt; mostly because it&amp;#39;s not very big
and has decent test coverage.
&lt;/p&gt;
&lt;p&gt;
I downloaded the project&amp;#39;s source code from the repository and
added a file named AutoMapper.msbuild to its root directory. You
can &lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.02/automapper.msbuild.zip"&gt;download 
this entire file&lt;/a&gt; but I&amp;#39;ll go over it piece by piece.
&lt;/p&gt;

&lt;p&gt;We start by just importing the MSBuild tasks that ship with NCover into our script and
declaring a few targets, including one to collect coverage data and one to generate the reports.
I added the NCover tasks dll to the project directory &lt;b&gt;tools/NCoverComplete&lt;/b&gt;.&lt;/p&gt;

&lt;pre name="code" class="xml:nogutter"&gt;&amp;lt;Project DefaultTargets=&amp;quot;RebuildReports&amp;quot; 
  xmlns=&amp;quot;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot; &amp;gt;
  &amp;lt;UsingTask  TaskName=&amp;quot;NCover.MSBuildTasks.NCover&amp;quot; 
        AssemblyFile=&amp;quot;$(ProjectDir)tools\NCoverComplete\NCover.MSBuildTasks.dll&amp;quot;/&amp;gt;
  &amp;lt;UsingTask  TaskName=&amp;quot;NCover.MSBuildTasks.NCoverReporting&amp;quot; 
        AssemblyFile=&amp;quot;$(ProjectDir)tools\NCoverComplete\NCover.MSBuildTasks.dll&amp;quot;/&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;Configuration Condition=&amp;quot; &amp;#39;$(Configuration)&amp;#39; == &amp;#39;&amp;#39; &amp;quot;&amp;gt;Debug&amp;lt;/Configuration&amp;gt;
    &amp;lt;BuildDir&amp;gt;$(MSBuildProjectDirectory)\build\$(Configuration)&amp;lt;/BuildDir&amp;gt;
    &amp;lt;NUnitBinDirectoryPath&amp;gt;$(MSBuildProjectDirectory)\tools\NUnit&amp;lt;/NUnitBinDirectoryPath&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;Target Name=&amp;quot;RebuildReports&amp;quot; DependsOnTargets=&amp;quot;RunCoverage;ExportReports&amp;quot; &amp;gt;
    &amp;lt;Message Text=&amp;quot;We will rebuild the coverage data than refresh the reports.&amp;quot; 
          Importance=&amp;quot;High&amp;quot; /&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;RunCoverage&amp;quot; &amp;gt;
    &amp;lt;!-- snip --&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;ExportReports&amp;quot; &amp;gt;
    &amp;lt;!-- snip --&amp;gt;
  &amp;lt;/Target&amp;gt;
&amp;lt;/Project&amp;gt;&lt;/pre&gt;


&lt;p&gt;
	Now let&amp;#39;s look closely at the target that gathers the coverage data. All it
	does is tell NCover (NCover console, really) to run NUnit over the
	AutoMapper.UnitTests.dll and save all the output to well-known locations.
&lt;/p&gt;

&lt;pre name="code" class="xml:nogutter"&gt;&amp;lt;Target Name=&amp;quot;RunCoverage&amp;quot; &amp;gt;
  &amp;lt;Message Text=&amp;quot;Starting Code Coverage Analysis (NCover) ...&amp;quot; Importance=&amp;quot;High&amp;quot; /&amp;gt;
  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;NCoverOutDir&amp;gt;$(MSBuildProjectDirectory)\build\NCoverOut&amp;lt;/NCoverOutDir&amp;gt;
    &amp;lt;NUnitResultsFile&amp;gt;build\NCoverOut\automapper-nunit-result.xml&amp;lt;/NUnitResultsFile&amp;gt;
    &amp;lt;NUnitOutFile&amp;gt;build\NCoverOut\automapper-nunit-Out.txt&amp;lt;/NUnitOutFile&amp;gt;
    &amp;lt;InputFile&amp;gt;$(BuildDir)\UnitTests\AutoMapper.UnitTests.dll&amp;lt;/InputFile&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;NCover ToolPath=&amp;quot;$(ProgramFiles)\NCover&amp;quot;
    ProjectName=&amp;quot;$(Scenario)&amp;quot;
    WorkingDirectory=&amp;quot;$(MSBuildProjectDirectory)&amp;quot;   
    TestRunnerExe=&amp;quot;$(NUnitBinDirectoryPath)\nunit-console.exe&amp;quot;

    TestRunnerArgs=&amp;quot;$(InputFile) /xml=$(NUnitResultsFile) /out=$(NUnitOutFile)&amp;quot;

    AppendTrendTo=&amp;quot;$(NCoverOutDir)\automapper-coverage.trend&amp;quot;
    CoverageFile=&amp;quot;$(NCoverOutDir)\automapper-coverage.xml&amp;quot;
    LogFile=&amp;quot;$(NCoverOutDir)\automapper-coverage.log&amp;quot;
    IncludeTypes=&amp;quot;AutoMapper\..*&amp;quot;
    ExcludeTypes=&amp;quot;AutoMapper\.UnitTests\..*;AutoMapper\.Tests\..*&amp;quot;
    SymbolSearchLocations=&amp;quot;Registry, SymbolServer, BuildPath, ExecutingDir&amp;quot;
  /&amp;gt;
&amp;lt;/Target&amp;gt;&lt;/pre&gt;

&lt;p&gt;
	Of special interest in the NCover task above are the output files named
	&lt;b&gt;automapper)-coverage.xml&lt;/b&gt; and &lt;b&gt;automapper-coverage.trend&lt;/b&gt;, which
	contain the precious coverage data and historical trending respectively. In case
	you&amp;#39;re curious, the trend file is actually a SQLite3 database file that you
	can report directly from or export to other database formats if you want.
&lt;/p&gt;
&lt;p&gt;
	Also note the &lt;code&gt;IncludeTypes&lt;/code&gt; and &lt;code&gt;ExcludeTypes&lt;/code&gt; parameters,
	which guarantee that we are not tracking coverage on code that we don&amp;#39;t care about.
&lt;/p&gt;

&lt;p&gt;
	Now that we have our coverage and trend data collected and saved to
	files we know, we can run as many reports as we want without needing
	to execute the whole set of tests again. That&amp;#39;s in the next target.
&lt;/p&gt;


&lt;pre name="code" class="xml:nogutter"&gt;&amp;lt;Target Name=&amp;quot;ExportReports&amp;quot; &amp;gt;
  &amp;lt;Message Text=&amp;quot;Starting Producing NCover Reports...&amp;quot; Importance=&amp;quot;High&amp;quot; /&amp;gt;
  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;Scenario&amp;gt;AutoMapper-Full&amp;lt;/Scenario&amp;gt;
    &amp;lt;NCoverOutDir&amp;gt;$(MSBuildProjectDirectory)\build\NCoverOut&amp;lt;/NCoverOutDir&amp;gt;
    &amp;lt;RptOutFolder&amp;gt;$(NCoverOutDir)\$(Scenario)Coverage&amp;lt;/RptOutFolder&amp;gt;
    &amp;lt;Reports&amp;gt;
      &amp;lt;Report&amp;gt;
        &amp;lt;ReportType&amp;gt;FullCoverageReport&amp;lt;/ReportType&amp;gt;
        &amp;lt;OutputPath&amp;gt;$(RptOutFolder)\Full\index.html&amp;lt;/OutputPath&amp;gt;
        &amp;lt;Format&amp;gt;Html&amp;lt;/Format&amp;gt;
      &amp;lt;/Report&amp;gt;
      &amp;lt;Report&amp;gt;
        &amp;lt;ReportType&amp;gt;SymbolModuleNamespaceClass&amp;lt;/ReportType&amp;gt;
        &amp;lt;OutputPath&amp;gt;$(RptOutFolder)\ClassCoverage\index.html&amp;lt;/OutputPath&amp;gt;
        &amp;lt;Format&amp;gt;Html&amp;lt;/Format&amp;gt;
      &amp;lt;/Report&amp;gt;
      &amp;lt;Report&amp;gt;
        &amp;lt;ReportType&amp;gt;Trends&amp;lt;/ReportType&amp;gt;
        &amp;lt;OutputPath&amp;gt;$(RptOutFolder)\Trends\index.html&amp;lt;/OutputPath&amp;gt;
        &amp;lt;Format&amp;gt;Html&amp;lt;/Format&amp;gt;
      &amp;lt;/Report&amp;gt;
    &amp;lt;/Reports&amp;gt;
    &amp;lt;SatisfactoryCoverage&amp;gt;
      &amp;lt;Threshold&amp;gt;
        &amp;lt;CoverageMetric&amp;gt;MethodCoverage&amp;lt;/CoverageMetric&amp;gt;
        &amp;lt;Type&amp;gt;View&amp;lt;/Type&amp;gt;
        &amp;lt;Value&amp;gt;80.0&amp;lt;/Value&amp;gt;
      &amp;lt;/Threshold&amp;gt;
      &amp;lt;Threshold&amp;gt;
        &amp;lt;CoverageMetric&amp;gt;SymbolCoverage&amp;lt;/CoverageMetric&amp;gt;
        &amp;lt;Value&amp;gt;80.0&amp;lt;/Value&amp;gt;
      &amp;lt;/Threshold&amp;gt;
      &amp;lt;Threshold&amp;gt;
        &amp;lt;CoverageMetric&amp;gt;BranchCoverage&amp;lt;/CoverageMetric&amp;gt;
        &amp;lt;Value&amp;gt;80.0&amp;lt;/Value&amp;gt;
      &amp;lt;/Threshold&amp;gt;
      &amp;lt;Threshold&amp;gt;
        &amp;lt;CoverageMetric&amp;gt;CyclomaticComplexity&amp;lt;/CoverageMetric&amp;gt;
        &amp;lt;Value&amp;gt;8&amp;lt;/Value&amp;gt;
      &amp;lt;/Threshold&amp;gt;
    &amp;lt;/SatisfactoryCoverage&amp;gt;

  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;NCoverReporting 
    ToolPath=&amp;quot;$(ProgramFiles)\NCover&amp;quot;
    CoverageDataPaths=&amp;quot;$(NCoverOutDir)\automapper-coverage.xml&amp;quot;
    LoadTrendPath=&amp;quot;$(NCoverOutDir)\automapper-coverage.trend&amp;quot;
    ProjectName=&amp;quot;$(Scenario) Code&amp;quot;
    OutputReport=&amp;quot;$(Reports)&amp;quot;
    SatisfactoryCoverage=&amp;quot;$(SatisfactoryCoverage)&amp;quot;
  /&amp;gt;
&amp;lt;/Target&amp;gt;&lt;/pre&gt;

&lt;p&gt;
	What you can see in this target is that we are creating three different
	reports, represented by the &lt;code&gt;Report&lt;/code&gt; elements and that
	we are changing the satisfactory threshold to 80% code coverage 
	(down from the default of 95%) and the maximum cyclomatic complexity 
	to 8. These two blocks of configuration are passer to the NCoverReporting
	task via the parameters &lt;code&gt;OutputReport&lt;/code&gt; and &lt;code&gt;SatisfactoryCoverage&lt;/code&gt;, 
	respectively.
&lt;/p&gt;

&lt;p&gt;
	The above reports are shown in the images below.
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.02/ncover_2D00_full.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.02/ncover_2D00_full_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;

&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.02/ncover_2D00_class.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.02/ncover_2D00_class_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.02/ncover_2D00_trend.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.02/ncover_2D00_trend_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;
&lt;/p&gt;


&lt;h3&gt;Focus on specific areas&lt;/h3&gt;

&lt;p&gt;
	Let&amp;#39;s now say that, in addition to the reports for the entire source code, we
	also want to keep a closer eye on the classes under the &lt;code&gt;AutoMapper.Mappers&lt;/code&gt;
	namespace. We can get that going with another reporting target, filtering the reported
	data down to just the code we are interested in:
&lt;/p&gt;

&lt;pre name="code" class="xml:nogutter"&gt;&amp;lt;Target Name=&amp;quot;ExportReportsMappers&amp;quot; &amp;gt;
  &amp;lt;Message Text=&amp;quot;Reports just for the Mappers&amp;quot; Importance=&amp;quot;High&amp;quot; /&amp;gt;
  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;Scenario&amp;gt;AutoMapper-OnlyMappers&amp;lt;/Scenario&amp;gt;
    &amp;lt;NCoverOutDir&amp;gt;$(MSBuildProjectDirectory)\build\NCoverOut&amp;lt;/NCoverOutDir&amp;gt;
    &amp;lt;RptOutFolder&amp;gt;$(NCoverOutDir)\$(Scenario)Coverage&amp;lt;/RptOutFolder&amp;gt;
    &amp;lt;Reports&amp;gt;
      &amp;lt;Report&amp;gt;
        &amp;lt;ReportType&amp;gt;SymbolModuleNamespaceClass&amp;lt;/ReportType&amp;gt;
        &amp;lt;OutputPath&amp;gt;$(RptOutFolder)\ClassCoverage\index.html&amp;lt;/OutputPath&amp;gt;
        &amp;lt;Format&amp;gt;Html&amp;lt;/Format&amp;gt;
      &amp;lt;/Report&amp;gt;
      &amp;lt;!-- add more Report elements as desired --&amp;gt;
    &amp;lt;/Reports&amp;gt;
    &amp;lt;CoverageFilters&amp;gt;
      &amp;lt;Filter&amp;gt;
        &amp;lt;Pattern&amp;gt;AutoMapper\.Mappers\..*&amp;lt;/Pattern&amp;gt;
        &amp;lt;Type&amp;gt;Class&amp;lt;/Type&amp;gt;
        &amp;lt;IsRegex&amp;gt;True&amp;lt;/IsRegex&amp;gt;
        &amp;lt;IsInclude&amp;gt;True&amp;lt;/IsInclude&amp;gt;
      &amp;lt;/Filter&amp;gt;
      &amp;lt;!-- include/exclude more classes, assemblies, namespaces, 
      methods, files as desired --&amp;gt;
    &amp;lt;/CoverageFilters&amp;gt;

  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;NCoverReporting 
    ToolPath=&amp;quot;$(ProgramFiles)\NCover&amp;quot;
    CoverageDataPaths=&amp;quot;$(NCoverOutDir)\automapper-coverage.xml&amp;quot;
    ClearCoverageFilters=&amp;quot;true&amp;quot;
    CoverageFilters=&amp;quot;$(CoverageFilters)&amp;quot;
    LoadTrendPath=&amp;quot;$(NCoverOutDir)\automapper-coverage.trend&amp;quot;
    ProjectName=&amp;quot;$(Scenario) Code&amp;quot;
    OutputReport=&amp;quot;$(Reports)&amp;quot;
  /&amp;gt;
&amp;lt;/Target/&amp;gt;&lt;/pre&gt;

&lt;p&gt;
	Now that we have this basic template our plan is to identify
	problem areas in the code and create reports aimed at them.
	The URLs of the reports will be included in the CI build reports 
	and notification emails.
&lt;/p&gt;
&lt;p&gt;
	It&amp;#39;s so easy to add more reports that we will have reports
	that will live for a single release cycle or even less if
	we need it.
&lt;/p&gt;
&lt;p&gt;
	I hope this was helpful for more people because it did take
	a good amount of time to get it all sorted out. Even if
	you&amp;#39;re using NAnt instead of MSBuild, the syntax is
	similar and I&amp;#39;m sure you can port the idea easily.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55327" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term=".NET" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/.NET/default.aspx" /><category term="Tips-and-Tricks" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx" /><category term="Automation" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Automation/default.aspx" /><category term="UnitTesting" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/UnitTesting/default.aspx" /></entry><entry><title>How to detect the text encoding of a file</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/01/26/how-to-detect-the-text-encoding-of-a-file.aspx" /><id>/blogs/sergio_pereira/archive/2010/01/26/how-to-detect-the-text-encoding-of-a-file.aspx</id><published>2010-01-27T01:18:00Z</published><updated>2010-01-27T01:18:00Z</updated><content type="html">&lt;p&gt;
Today I needed a way to identify ANSI (Windows-1252) and UTF-8 files in a directory filled with files of
these two types. I was surprised to not find a simple way of doing this via a property of method somewhere
under the &lt;code&gt;System.IO&lt;/code&gt; namespace.
&lt;/p&gt;
&lt;p&gt;
Not that it&amp;#39;s that hard to identify the encoding programmatically, but it&amp;#39;s always better when you
don&amp;#39;t need to write a method yourself. Anyway, here&amp;#39;s what I came up with. It detects UTF-8 encoding
based on the encoding signature added to the beginning of the file.
&lt;/p&gt;
&lt;p&gt;
The code below is specific to UTF-8 but shouldn&amp;#39;t be too hard to extend the example to
detect more encodings.
&lt;/p&gt;
&lt;pre name="code" class="csharp:nogutter"&gt;public static bool IsUtf8(string fname){
  using(var f = File.Open(fname, FileMode.Open)){
    var sig = new byte[Encoding.UTF8.GetPreamble().Length];
    f.Read(sig, 0, sig.Length);
    return sig.SequenceEqual(Encoding.UTF8.GetPreamble());
  }
}&lt;/pre&gt;

&lt;p&gt;
Maybe I just looked in the wrong places. Does anyone know a simpler way in the framework to accomplish this?
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55142" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term=".NET" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/.NET/default.aspx" /><category term="Tips-and-Tricks" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx" /></entry><entry><title>On ALT.NET and patience</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/01/19/on-alt-net-and-patience.aspx" /><id>/blogs/sergio_pereira/archive/2010/01/19/on-alt-net-and-patience.aspx</id><published>2010-01-19T20:42:00Z</published><updated>2010-01-19T20:42:00Z</updated><content type="html">&lt;p&gt;
There ALT.NET bashing season is on full steam. Ian Cooper has a &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2010/01/19/whither-alt-net.aspx"&gt;thorough post&lt;/a&gt; about it.
&lt;/p&gt;
&lt;p&gt;
To my recollection, ALT.NET was formed by people that shared very similar tastes on what 
represents good development tools, practices, and methodologies. This group of people, 
just by the simple fact that they decided to get together under one roof to discuss these 
ideas, showed that they are constantly and decidedly trying to become better at what 
they do.

&lt;/p&gt;

&lt;p&gt;But when you take the step to form a new community or movement (or whatever else you
want to call it) you can&amp;#39;t easily control who jumps on board or who jumps ship - and 
you shouldn&amp;#39;t even try to.
&lt;/p&gt;
&lt;p&gt;Inevitably the original idea started to attract many different kinds of participants, 
which I&amp;#39;m going to roughly distribute in the below four categories (I was tempted to 
use the term personas, but … never mind.)
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		&lt;b&gt;I&amp;#39;m here to help&lt;/b&gt;&lt;br /&gt;
		&lt;ul&gt;
			&lt;li&gt;I like to teach,&lt;/li&gt;
			&lt;li&gt;to write,&lt;/li&gt;
			&lt;li&gt;to contribute to OSS,&lt;/li&gt;
			&lt;li&gt;coordinating UGs and events&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;b&gt;Those who like to complain&lt;/b&gt;&lt;br /&gt;
		A very minor percentage of those know how to externalize their criticism in a constructive way. Unfortunately 
		the majority limit their contributions to rants and trolling. &lt;br /&gt;
		That&amp;#39;s probably the only group of people that I&amp;#39;d try to weed out if I could (but I can&amp;#39;t; and we shouldn&amp;#39;t).
	&lt;/li&gt;
	&lt;li&gt;
		&lt;b&gt;Those who want to learn&lt;/b&gt;&lt;br /&gt;
		&lt;ul&gt;
			&lt;li&gt;They want to hear about other ideas,&lt;/li&gt;
			&lt;li&gt;to figure out how to bring better practices to their work,&lt;/li&gt;
			&lt;li&gt;they have a specific problem and they&amp;#39;re seeking opinions or answers.&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;b&gt;Heliotropic migrants&lt;/b&gt;&lt;br /&gt;
		The ones who want to be linked to (and hops on) every new, shiny thing for commercial 
		reasons. There&amp;#39;s always this type of people. They need to latch on to what 
		could be the next big thing for the sake of their own livelihood. There&amp;#39;s 
		nothing wrong with that, by the way.
	&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Some people just can&amp;#39;t put up with the other types. Some folks go ballistic with 
people on &lt;b&gt;#4&lt;/b&gt;, others can&amp;#39;t stand the whiners in &lt;b&gt;#2&lt;/b&gt;. Some don&amp;#39;t tolerate repeated or trivial questions 
from folks that are just trying to learn.
&lt;/p&gt;

&lt;p&gt;In the midst of all this, it becomes hard to connect &lt;b&gt;#1&lt;/b&gt; and &lt;b&gt;#3&lt;/b&gt;, which I think is 
the ultimate reason for ALT.NET existence.
&lt;/p&gt;

&lt;p&gt;Frankly speaking, I think I&amp;#39;ve personally danced around in all these four categories 
but I find myself most of the time in &lt;b&gt;#3&lt;/b&gt; and some other times in &lt;b&gt;#1&lt;/b&gt;. I do apologize 
for my ventures in &lt;b&gt;#2&lt;/b&gt; – it&amp;#39;s hard to avoid.
&lt;/p&gt;

&lt;p&gt;So, if you dabble in the ALT.NET waters, let me just ask you to exercise a little 
bit of patience. We all still have a lot to learn and there&amp;#39;s very good indications that 
some of those lessons are permeating the .NET development community &amp;mdash;
from the individual developer to the big Enterprise, Inc.
&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s no try to change the world with a single swing of the bat. Changing one 
constructor method at a time will get us further. In the end, the idea is simply to 
more efficiently produce more maintainable and reliable software.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55063" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="alt.net" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/alt.net/default.aspx" /><category term="Community" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Community/default.aspx" /></entry><entry><title>Oh, no. My TortoiseSVN overlays are missing</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/01/05/oh-no-my-tortoisesvn-overlays-are-missing.aspx" /><id>/blogs/sergio_pereira/archive/2010/01/05/oh-no-my-tortoisesvn-overlays-are-missing.aspx</id><published>2010-01-05T09:13:00Z</published><updated>2010-01-05T09:13:00Z</updated><content type="html">	&lt;p&gt;It&amp;#39;s a matter of time. Good were the days when almost no application
	knew how to put overlays on your file icons in Explorer. These days it
	seems this is the coolest thing ever and virtually all file system type
	of utilities&lt;a href="http://stackoverflow.com/questions/843506/shell-icon-overlay-c"&gt; want to add their own&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;Sooner or later you will install some utility and not notice anything different. But
	after the next reboot, poof, your &lt;a href="http://tortoisesvn.net/"&gt;TortoiseSVN&lt;/a&gt; overlays are gone. And,
       depending on
	how much time elapsed between the utility installation and that reboot,
	you may not have the slightest clue of what happened. Reinstalling
	TSVN won&amp;#39;t fix it&lt;/p&gt;

	&lt;h3&gt;TFS Power tools, Dropbox, Mozy, stop breaking my TSVN overlays&lt;/h3&gt;

	&lt;p&gt;I should not blame these applications for a Windows shell
	limitation. To be fair, TSVN is the greater offender of them all.&lt;/p&gt;

	&lt;p&gt;It seems that the shell only supports 15 different
	icon overlays and TSVN creates 9 of those. After 15 the 
	shell starts ignoring the extra ones. The trick is that
	Windows chooses the first 15 alphabetically from their entries in
	the system registry.&lt;/p&gt;

	&lt;h3&gt;I love simple fixes&lt;/h3&gt;

	&lt;p&gt;The fix is rather obvious; just make sure the overlays you
	want to be active are registered alphabetically before the
	ones you can live without.&lt;/p&gt;

	&lt;p&gt;Open the registry editor and go to 
	&lt;b&gt;HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers&lt;/b&gt;
	and look at all the child keys in there. It will be obvious that, if you want to
	preserve the TSVN overlays like me, you need to keep the ones starting with Tortoise*
	before the other ones. 
	&lt;/p&gt;
	&lt;p&gt;If you look at the image below you&amp;#39;ll see that I changed my entries by
	prefixing the undesirable ones with &lt;b&gt;z_&lt;/b&gt;, following 
	&lt;a href="http://blog.falafel.com/2009/12/17/WindowsIconOverlayLimitations.aspx"&gt;someone else&amp;#39;s suggestion&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.01/registry_2D00_overlays.PNG" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;After that change you just need to kill and restart explorer.exe using Task Manager (or
	logoff or reboot the machine depending on your tolerance to pain.)
	&lt;/p&gt;

	&lt;p&gt;
		I believe this is a common problem so I hope this tip helps somebody.
	&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54881" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="Development" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Development/default.aspx" /><category term="Tips-and-Tricks" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx" /></entry><entry><title>Language Envy - C# needs Ranges</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2010/01/02/language-envy-c-needs-ranges.aspx" /><id>/blogs/sergio_pereira/archive/2010/01/02/language-envy-c-needs-ranges.aspx</id><published>2010-01-02T10:55:00Z</published><updated>2010-01-02T10:55:00Z</updated><content type="html">	&lt;p&gt;
		As soon as I started learning Ruby, a few years ago, I got immediately hooked 
		on its &lt;a href="http://ruby-doc.org/core/classes/Range.html"&gt;&lt;code&gt;Range&lt;/code&gt;&lt;/a&gt; class. 
		I could not believe I had been programming in .NET without them for so long.
	&lt;/p&gt;

	&lt;p&gt;
		I like to think of range objects as the specification for a &lt;code&gt;for&lt;/code&gt;
		loop, packaged in an object that can be passed around. That&amp;#39;s not the whole story, though.
		Ranges also represent sequences or intervals, which can be queried for intersection or
		containment. See the following Ruby sample code.
	&lt;/p&gt;

		&lt;pre name="code" class="ruby:nogutter"&gt;#declare a Range object
summer_months = 6..9
#enumerate it
summer_months.each {|m| puts &amp;quot;#{Date.new(2000, m, 1).strftime(&amp;#39;%B&amp;#39;)} is a Summer month.&amp;quot; }
#other handy features
summer_months.include? 7 # ==&amp;gt; true
summer_months.to_a # ==&amp;gt; [6, 7, 8, 9]  (converted to array)&lt;/pre&gt;


	&lt;h3&gt;I needed that in C#&lt;/h3&gt;
	&lt;p&gt;
		That was back when the CLR 2.0 was just about to be released and I ended up
		writing my own Range&lt;/code&gt; class. I have used this class in a handful of
		projects since then and I&amp;#39;m still surprised that we don&amp;#39;t have it in the
		standard .NET class library. The closest thing I&amp;#39;m aware of is the method
		&lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.range.aspx"&gt;&lt;code&gt;System.Linq.Enumerable.Range(int, int)&lt;/code&gt;&lt;/a&gt;,
		which is rather limited (it only enumerates integers one by one).
	&lt;/p&gt;

	&lt;p&gt;
		Here&amp;#39;s the code that I came up with, which has served me well for many years. First 
		an abstract base class. I&amp;#39;ll omit parts of the code for brevity but I&amp;#39;ll give you 
		a link for the complete source at the end.
	&lt;/p&gt;

	&lt;pre name="code" class="csharp:nogutter"&gt;public abstract class RangeBase&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt; where T : IComparable
{
  public T Start { get; set; }
  public T End { get; set; }

  protected RangeBase(T start, T end)
  {
    // ... snip ...
  }

  protected abstract T GetNextItem(T currentItem);

  public IEnumerator&amp;lt;T&amp;gt; GetEnumerator()
  {
    T item = Start;

    while (true)
    {
      if (item.CompareTo(End) &amp;gt; 0)
        break;

      yield return item;

      item = GetNextItem(item);
    }
  }


  IEnumerator IEnumerable.GetEnumerator()
  {
    return GetEnumerator();
  }

  public bool Intersects(RangeBase&amp;lt;T&amp;gt; otherRange)
  {
    // ... snip ...
  }

  public bool Contains(RangeBase&amp;lt;T&amp;gt; otherRange)
  {
    // ... snip ...
  }

  public bool Contains(T element)
  {
    return (Start.CompareTo(element) &amp;lt;= 0) &amp;amp;&amp;amp; (End.CompareTo(element) &amp;gt;= 0);
  }
}&lt;/pre&gt;

	&lt;p&gt;
		There&amp;#39;s also a generic concrete type and a bunch of the more common
		implementations for convenience.
	&lt;/p&gt;

	&lt;pre name="code" class="csharp:nogutter"&gt;public class Range&amp;lt;T&amp;gt; : RangeBase&amp;lt;T&amp;gt; where T : IComparable
{
  public Func&amp;lt;T, T&amp;gt; GetNext { get; private set; }

  public Range(T start, T end, Func&amp;lt;T, T&amp;gt; getNext)
    : base(start, end)
  {
    GetNext = getNext;
  }

  protected override T GetNextItem(T currentItem)
  {
    return GetNext(currentItem);
  }
}

public class Int32Range : RangeBase&amp;lt;int&amp;gt;
{
  public Int32Range(int start, int end) : base(start, end){}
  protected override int GetNextItem(int currentItem)
  {
    return currentItem + 1;
  }
}

public class Int64Range : RangeBase&amp;lt;long&amp;gt; { /* ... snip ... */ }
public class DayRange : RangeBase&amp;lt;DateTime&amp;gt; { /* ... snip ... */ }
public class HourRange : RangeBase&amp;lt;DateTime&amp;gt; { /* ... snip ... */ }
//...etc...&lt;/pre&gt;


	&lt;h3&gt;Coding with Ranges&lt;/h3&gt;
	&lt;p&gt;
		With the above classes I can write code that is similar in functionality to the
		Ruby version.
	&lt;/p&gt;
	&lt;pre name="code" class="csharp:nogutter"&gt;//declare a range of numbers
var summerMonths = new Int32Range(6, 9);
//enumerate it
foreach(var m in summerMonths) 
  Console.WriteLine(new DateTime(2000, m, 1).ToString(&amp;quot;MMMM&amp;quot;) + &amp;quot; is a Summer month.&amp;quot;);
//other handy features
summerMonths.Contains(7); // ==&amp;gt; true
summerMonths.Contains(new Int32Range(7, 8)); // ==&amp;gt; true
summerMonths.ToArray(); // ==&amp;gt; [6, 7, 8, 9]  (using LINQ extensions)&lt;/pre&gt;

	&lt;p&gt;
		We can also use the generic &lt;code&gt;Range&lt;/code&gt; type to create less orthodox
		iterations, like a sequence of dates that repeat &lt;i&gt;every other week&lt;/i&gt;:
	&lt;/p&gt;

&lt;pre name="code" class="csharp:nogutter"&gt;var startDate = new DateTime(2010, 1, 1);
var endDate = startDate.AddMonths(3);
var appointmentDates = new Range&amp;lt;DateTime&amp;gt;(startDate, endDate, d =&amp;gt; d.AddDays(14));
appointmentDates.ToArray(); 
// ==&amp;gt; [ 1/1/2010, 1/15/2010, 1/29/2010, 
//          2/12/2010, 2/26/2010, 3/12/2010, 3/26/2010 ]&lt;/pre&gt;

	&lt;p&gt;
		The complete source for these classes and even some unit tests can be found
		&lt;a href="http://github.com/sergiopereira/juicy/blob/master/src/Juicy.Core/Ranges.cs"&gt;here&lt;/a&gt;.
	&lt;/p&gt;

	&lt;h3&gt;Other implementations&lt;/h3&gt;
	&lt;p&gt;
		Of course I was not the first to implement a Range class in C#. A quick search
		yielded at least a 
		&lt;a href="http://www.pluralsight.com/community/blogs/dbox/archive/2005/04/24/7690.aspx"&gt;couple&lt;/a&gt;
		of &lt;a href="http://andyclymer.blogspot.com/2009/03/ruby-ranges-in-net.html"&gt;articles&lt;/a&gt; with
		different approaches to the same goal.
	&lt;/p&gt;
 &lt;p&gt;Another indication that ranges are a popular data structure is the fact that F# has them too.
With luck we will see ranges in a future version of the .NET framework. Oh, 
and since we are wishing for things. let&amp;#39;s hope they introduce range literals in C# at that same time.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54862" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term=".NET" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/.NET/default.aspx" /><category term="Ruby" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Ruby/default.aspx" /><category term="Series" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Series/default.aspx" /><category term="Language-Envy" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Language-Envy/default.aspx" /><category term="Juicy" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Juicy/default.aspx" /></entry><entry><title>2009 Visual Summary</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2009/12/24/2009-visual-summary.aspx" /><id>/blogs/sergio_pereira/archive/2009/12/24/2009-visual-summary.aspx</id><published>2009-12-24T18:19:00Z</published><updated>2009-12-24T18:19:00Z</updated><content type="html">&lt;p&gt;
If you&amp;#39;ve been reading this blog in 2009, here&amp;#39;s a good, speed-of-light recap. And, since I avoid writing about the blog itself or blogging in general, that&amp;#39;s all I&amp;#39;m going to say about it.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.12/words_2D00_2009.png"&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.12/words_2D00_2009_2D00_small.png" border="0" alt="2009 summary - click for larger version" /&gt;
&lt;a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;i&gt;(Created with &lt;a href="http://www.wordle.net/"&gt;Wordle&lt;/a&gt;)&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54740" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author></entry><entry><title>Guided Tour: jQuery - Array wannabes</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2009/12/22/guided-tour-jquery-array-wannabes.aspx" /><id>/blogs/sergio_pereira/archive/2009/12/22/guided-tour-jquery-array-wannabes.aspx</id><published>2009-12-23T05:13:00Z</published><updated>2009-12-23T05:13:00Z</updated><content type="html">	

	&lt;div class="note"&gt;
		This post is part of a series called the &lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/tags/GuidedTour/default.aspx"&gt;Guided Tours&lt;/a&gt;.
	&lt;/div&gt;

	&lt;p&gt;
		In this second installment we are still looking inside the jQuery code.
		Trust me, even if it&amp;#39;s hard to digest, you can still learn enough
		if you focus on a little bit at a time.
	&lt;/p&gt;

	&lt;p&gt;
		The code we are interested in today is the following.
	&lt;/p&gt;

	&lt;pre name="code" class="js:nogutter"&gt;//from jQuery 1.3.2
get: function( num ) {
	return num === undefined ?

		// Return a &amp;#39;clean&amp;#39; array
		Array.prototype.slice.call( this ) : 

		// Return just the object
		this[ num ];
},&lt;/pre&gt;

	&lt;p&gt;
		That&amp;#39;s the code for the command &lt;code&gt;&lt;a href="http://docs.jquery.com/Core/get"&gt;jQuery.fn.get(index)&lt;/a&gt;&lt;/code&gt;, 
		which returns the element at the given index or the entire array if the index is
		omitted.
	&lt;/p&gt;

	&lt;p&gt;
		The JavaScript idiom that is really interesting in this function is that
		strangely long function call &lt;code&gt;Array.prototype.slice.call( this )&lt;/code&gt;.
	&lt;/p&gt;

	&lt;p&gt;
		That line is needed because we need to return an array and, even though they look like one, &lt;i&gt;the
		jQuery objects aren&amp;#39;t arrays&lt;/i&gt;. And they aren&amp;#39;t alone in that.
	&lt;/p&gt;

	&lt;h3&gt;If it walks like a duck...&lt;/h3&gt;

	&lt;p&gt;
		The &lt;code&gt;Array&lt;/code&gt; object is one that we can&amp;#39;t avoid becoming
		familiar with in JavaScript. They are everywhere. Data is passed
		to functions as arrays. Data is returned in arrays.
		&lt;b&gt;Or are they?&lt;/b&gt;
	&lt;/p&gt;

	&lt;p&gt;
		Aside from jQuery objects there are at least two other important occurrences
		of data structures that are used like arrays but really aren&amp;#39;t: the
		&lt;code&gt;&lt;a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Functions_and_function_scope/arguments"&gt;arguments&lt;/a&gt;
		&lt;/code&gt; variable and the DOM &lt;code&gt;&lt;a href="https://developer.mozilla.org/En/DOM/NodeList"&gt;NodeList&lt;/a&gt;&lt;/code&gt;
		collections.
	&lt;/p&gt;

	&lt;p&gt;
		The &lt;code&gt;arguments&lt;/code&gt; variable is the list of parameters passed to 
		the current function and the &lt;code&gt;NodeList&lt;/code&gt; is what is returned from members of the the DOM API such as
		&lt;code&gt;document.getElementsByTagName()&lt;/code&gt; or &lt;code&gt;element.childNodes&lt;/code&gt;.
		Both of these types have a &lt;code&gt;length&lt;/code&gt; property and expose their
		items with indices, like &lt;code&gt;arguments[1]&lt;/code&gt; or &lt;code&gt;elements[0]&lt;/code&gt;.
	&lt;/p&gt;

	&lt;p&gt;
		But don&amp;#39;t let this small coincidence fool you. As soon as you stop paying attention
		and try to use another array method, like &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;shift&lt;/code&gt;, 
		&lt;code&gt;join&lt;/code&gt; you&amp;#39;ll have your dreams shattered and a 
               &lt;code&gt;&lt;a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/TypeError"&gt;TypeError&lt;/a&gt;&lt;/code&gt;to handle.
	&lt;/p&gt;

	&lt;h3&gt;Help me, jQuery&lt;/h3&gt;

	&lt;p&gt;
		To solve the above problem and return a real array object instead of the jQuery
		object itself, the code used the technique we highlighted.
	&lt;/p&gt;

	&lt;pre name="code" class="js:nogutter"&gt;Array.prototype.slice.call( this )&lt;/pre&gt;

	&lt;p&gt;
		The idea is to use the 
		&lt;code&gt;&lt;a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/slice"&gt;array.slice()&lt;/a&gt;&lt;/code&gt;
		instance method
		to create a new array. The &lt;code&gt;slice&lt;/code&gt; method returns a chunk of the array and it
		takes two optional parameters (the boundaries) that, when omitted, make the function return
		a copy of the array itself.
	&lt;/p&gt;

	&lt;p&gt;
		I&amp;#39;ve written about the 
		&lt;code&gt;&lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/06/12/javascript-not-your-father-s-inheritance-model-part-1.aspx"&gt;prototype&lt;/code&gt; 
		object&lt;/a&gt; and 
		&lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx"&gt;how to invoke functions with &lt;code&gt;call&lt;/code&gt;&lt;/a&gt; 
		in previous posts, so I won&amp;#39;t
		repeat myself here. I&amp;#39;ll just add a reminder that the &lt;code&gt;this&lt;/code&gt; object in the &lt;code&gt;get&lt;/code&gt;
		method is the jQuery instance we&amp;#39;re working with.
	&lt;/p&gt;

	&lt;p&gt;
		What&amp;#39;s going on in &lt;code&gt;call( this )&lt;/code&gt; is that &lt;code&gt;slice&lt;/code&gt; is 
		being invoked as if it was a method of the jQuery object (note: the jQuery object
		does have a method called &lt;code&gt;&lt;a href="http://docs.jquery.com/Traversing/slice"&gt;slice&lt;/a&gt;&lt;/code&gt; but it 
		does not return an array.) 
	&lt;/p&gt;
	&lt;p&gt;
		You may be wondering how can we pass a jQuery object to
		&lt;code&gt;slice.call()&lt;/code&gt; and not get any errors inside the method implementation. Well,
		it works because the &lt;code&gt;slice&lt;/code&gt; method 
               &lt;a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array#Generic_methods"&gt;was built to be generic&lt;/a&gt; and it
		only needs that the current object has a &lt;code&gt;length&lt;/code&gt; property and items
		in indexed positions. That&amp;#39;s &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;Duck
		Typing&lt;/a&gt; at work.
	&lt;/p&gt;

	&lt;h3&gt;A Freebie&lt;/h3&gt;
	&lt;p&gt;
		There&amp;#39;s a small variation of this technique that you may come across in JavaScript
		as well.
	&lt;/p&gt;

	&lt;pre name="code" class="js:nogutter"&gt;[].slice.call( this )&lt;/pre&gt;

	&lt;p&gt;
		It calls the same &lt;code&gt;slice&lt;/code&gt; method but in a tad more wasteful manner
		because a new &lt;code&gt;Array&lt;/code&gt; instance is created each time just to provide access to its &lt;code&gt;slice&lt;/code&gt; method.
	&lt;/p&gt;

	&lt;p&gt;
		Well, that&amp;#39;s it. I hope you don&amp;#39;t scratch your head any longer when you see
		an expression like &lt;code&gt;XYZ.prototype.someMethod.call(obj)&lt;/code&gt; from now on.
	&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54712" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="Series" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Series/default.aspx" /><category term="JavaScript" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx" /><category term="jQuery" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/jQuery/default.aspx" /><category term="GuidedTour" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/GuidedTour/default.aspx" /></entry><entry><title>Guided Tour: jQuery - guard and default operators</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2009/12/09/guided-tour-jquery-guard-and-default-operators.aspx" /><id>/blogs/sergio_pereira/archive/2009/12/09/guided-tour-jquery-guard-and-default-operators.aspx</id><published>2009-12-09T10:50:00Z</published><updated>2009-12-09T10:50:00Z</updated><content type="html">	&lt;div class="note"&gt;
		This post is part of a series called the &lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/tags/GuidedTour/default.aspx"&gt;Guided Tours&lt;/a&gt;.
	&lt;/div&gt;
	

	&lt;p&gt;I&amp;#39;m sure I&amp;#39;m not alone when I say that one of the best ways to improve our
	coding skills is by reading code written by someone else. Sometimes we
	don&amp;#39;t realize how lucky we are to have so much source code at our
	fingertips, namely Open Source Software.&lt;/p&gt;

	&lt;h3&gt;The guided tours&lt;/h3&gt;

	&lt;p&gt;With this post I&amp;#39;ll start another unbound series where I highlight 
	some interesting piece of code that I studied. I&amp;#39;ll share
	my notes and do my best to explain what I learned from it.&lt;/p&gt;

	&lt;h3&gt;jQuery: Eating the elephant one bite at a time&lt;/h3&gt;

	&lt;p&gt;I wouldn&amp;#39;t dare to start things off with a complete overview of jQuery. It&amp;#39;s
	a massive chunk of JavaScript and I&amp;#39;m afraid there isn&amp;#39;t an easy entry point
	in the source code.&lt;/p&gt;

	&lt;p&gt;I chose to find parts of it that are relatively easy to explain separately
	from the rest and that contain something worth explaining. I&amp;#39;ll do at least a
	few of those from jQuery but my plan is to not keep this series tied to
	jQuery or even JavaScript.&lt;/p&gt;

	&lt;h3&gt;The code under the microscope&lt;/h3&gt;

	&lt;p&gt;We&amp;#39;re going to take a look at &lt;code&gt;&lt;a href="http://docs.jquery.com/Attributes/text"&gt;jQuery.fn.text()&lt;/a&gt;&lt;/code&gt;,
	which returns the textual content of all the elements in the jQuery wrapped set,
	combined in a single string.&lt;/p&gt;

&lt;p&gt;	Here&amp;#39;s the code from jQuery version 1.3.2.
&lt;/p&gt;
	&lt;pre name="code" class="js:nogutter"&gt;text: function( text ) {
  if ( typeof text !== &amp;quot;object&amp;quot; &amp;amp;&amp;amp; text != null )
    return this.empty().append( 
	   (this[0] &amp;amp;&amp;amp; this[0].ownerDocument || document).createTextNode( text ) 
	);

  var ret = &amp;quot;&amp;quot;;

  jQuery.each( text || this, function(){
    jQuery.each( this.childNodes, function(){
      if ( this.nodeType != 8 )
        ret += this.nodeType != 1 ?
          this.nodeValue :
          jQuery.fn.text( [ this ] );
    });
  });

  return ret;
},&lt;/pre&gt;

	&lt;p&gt;The &lt;code&gt;text()&lt;/code&gt; function can be called with or without arguments, so 
	initially it tries to detect if a string argument was passed to it, in which
	case it will be made the content of the elements in the jQuery object.&lt;/p&gt;

	&lt;p&gt;Be aware that in all methods defined inside &lt;code&gt;jQuery.fn&lt;/code&gt; the
	value of &lt;code&gt;this&lt;/code&gt; will be the current jQuery object.&lt;/p&gt;

	&lt;p&gt;The first thing that caught my attention was the following expression:&lt;/p&gt;

	&lt;pre name="code" class="js:nogutter"&gt;(this[0] &amp;amp;&amp;amp; this[0].ownerDocument || document)&lt;/pre&gt;

	&lt;p&gt;In the context of the code it&amp;#39;s expected to return a DOM document object, but it&amp;#39;s
	a boolean expression, isn&amp;#39;t it? What gives?&lt;/p&gt;

	&lt;p&gt;Well, yes, it is a boolean expression. That leads me to explain a subtle but powerful
	difference between boolean operators in JavaScript to many other languages you may
	be more used to.&lt;/p&gt;

	&lt;h3&gt;Guard and Default operators&lt;/h3&gt;

	&lt;p&gt;The way I like to describe the boolean operators &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt;
	is: &lt;i&gt;They return the operand that short-circuited and resolved the expression.&lt;/i&gt; To
	put in a different way, when the JS interpreter detects that one of the operands has a 
	value that makes the remainder of the comparison irrelevant, it stops right there and 
	that operand (not necessarily &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;) becomes the
	result of the boolean expression.&lt;/p&gt;

	&lt;div class="note"&gt;&lt;span class="legend"&gt;Truthy and Falsy:&lt;/span&gt;
	In the context of a boolean expression, any value in JavaScript has a boolean meaning.
	It&amp;#39;s actually easy to memorize which mean which. The values that are treated as &lt;i&gt;false&lt;/i&gt;
	are: &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, 
	&lt;code&gt;&amp;quot;&amp;quot;&lt;/code&gt; (empty string), and &lt;code&gt;NaN&lt;/code&gt;. We call them &lt;i&gt;falsy&lt;/i&gt;.
	Everything else is treated as &lt;i&gt;true&lt;/i&gt; and we call them &lt;i&gt;truthy&lt;/i&gt;.
	&lt;/div&gt;

	&lt;p&gt;Here are some examples:&lt;/p&gt;

	&lt;table&gt;
		&lt;tr&gt;&lt;td&gt;
			&lt;table border="1"&gt;
				&lt;tr&gt;&lt;th&gt;A&lt;/th&gt;&lt;th&gt;B&lt;/th&gt;&lt;th&gt;A &amp;amp;&amp;amp; B&lt;/th&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;false&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;null&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;0&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;null&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;456&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;456&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;&amp;quot;text&amp;quot;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;&amp;quot;text&amp;quot;&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;&amp;quot;text&amp;quot;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;true&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
			&lt;/table&gt;
		&lt;/td&gt;
		&lt;td&gt;
			&lt;table border="1"&gt;
				&lt;tr&gt;&lt;th&gt;A&lt;/th&gt;&lt;th&gt;B&lt;/th&gt;&lt;th&gt;A || B&lt;/th&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;123&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;123&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;123&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;123&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;null&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;123&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;456&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;123&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;123&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;&amp;quot;text&amp;quot;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;123&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
				&lt;tr&gt;&lt;td&gt;&lt;code&gt;&amp;quot;text&amp;quot;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;&lt;code&gt;&amp;quot;text&amp;quot;&lt;/code&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
			&lt;/table&gt;
		&lt;/td&gt;&lt;/tr&gt;
	&lt;/table&gt;

	&lt;p&gt;Because of the above behavior, these boolean operators are often used as &lt;b&gt;Guard&lt;/b&gt; or &lt;b&gt;Default&lt;/b&gt;
	operators. The &lt;i&gt;guard&lt;/i&gt; operation is commonly used when you want to avoid a null or undefined reference error:&lt;/p&gt;

	&lt;pre name="code" class="js:nogutter"&gt;//someObj can be null. text will also be null in that case.
var text = someObj &amp;amp;&amp;amp; someObj.toString();&lt;/pre&gt;

	&lt;p&gt;Which is a shorthand for:&lt;/p&gt;

	&lt;pre name="code" class="js:nogutter"&gt;var text = null;
if (someObj !== null) {
  text = someObj.toString();
}&lt;/pre&gt;

	&lt;p&gt;The &lt;i&gt;default&lt;/i&gt; operation is arguably a much more common occurrence. We see it a lot when
	functions support optional arguments with default values. When a value is not given for
	a function parameter, it becomes &lt;code&gt;undefined&lt;/code&gt;. We can detect that and give a
	default value like this:&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;function addAll(numbersArray, step) {
  step = step || 1;
  var sum = 0;
  for (var i = 0; i &amp;lt; numbersArray.length; i += step) {
    sum += numbersArray[i];
  }
  return sum;
}
addAll([1, 2, 3, 4, 5, 6]); // ==&amp;gt; 21
addAll([1, 2, 3, 4, 5, 6], 3); // ==&amp;gt; 5&lt;/pre&gt;
	
	&lt;p&gt;In the above example, the &lt;code&gt;step&lt;/code&gt; parameter is optional. Not providing it
	would cause a problem if we hadn&amp;#39;t defaulted it to one right at the beginning of
	the function.&lt;/p&gt;

	&lt;p&gt;Wow. We sure covered a lot of stuff just to explain a simple boolean expression.
	The good news is that we will see a lot of that in the jQuery code (or in pretty
	much any decent JS code base) so it&amp;#39;s good to understand it well.&lt;/p&gt;

	&lt;p&gt;Back to our original expression.&lt;/p&gt;

	&lt;pre name="code" class="js:nogutter"&gt;(this[0] &amp;amp;&amp;amp; this[0].ownerDocument || document)&lt;/pre&gt;

	&lt;p&gt;Armed with our new understanding we can finally read this expression as:
	&lt;i&gt;If &lt;code&gt;this.ownerDocument&lt;/code&gt; exists I want that, otherwise just give me the
	global &lt;code&gt;document&lt;/code&gt; object.&lt;/i&gt; This returned DOM document object will
	be the owner document of new text value being inserted.
	&lt;/p&gt;

	&lt;h3&gt;What about the rest of that function&lt;/h3&gt;

	&lt;p&gt;It&amp;#39;s funny that a tiny bit of that function became this long post. But 
	the remainder of the function, in its majority, isn&amp;#39;t really all that interesting
	in terms of  JavaScript. It&amp;#39;s mostly boring DOM navigation, done recursively.
	If you know how to use the 
	&lt;code&gt;&lt;a href="http://docs.jquery.com/Utilities/jQuery.each"&gt;jQuery.each()&lt;/a&gt;&lt;/code&gt;
	utility function, you can figure out that code on your own.&lt;/p&gt;

	&lt;p&gt;Our time here is up and we have a whole lot more of
	code sightseeing to do.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54358" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="Series" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Series/default.aspx" /><category term="JavaScript" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx" /><category term="jQuery" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/jQuery/default.aspx" /><category term="GuidedTour" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/GuidedTour/default.aspx" /></entry><entry><title>Test-Driving a new feature for JavaScript</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2009/11/12/test-driving-a-new-feature-for-javascript.aspx" /><id>/blogs/sergio_pereira/archive/2009/11/12/test-driving-a-new-feature-for-javascript.aspx</id><published>2009-11-13T01:16:00Z</published><updated>2009-11-13T01:16:00Z</updated><content type="html">&lt;/p&gt;
Earlier this week I had a piece of JavaScript that I wanted to like this:
&lt;p&gt;

&lt;pre name="code" class="js:nogutter"&gt;var index = someArray.indexOf(someObject);&lt;/pre&gt;

&lt;p&gt;
The problem there is that the &lt;code&gt;indexOf&lt;/code&gt; method of
the &lt;code&gt;Array&lt;/code&gt; object was introduced in JavaScript 1.6,
which &lt;a href="http://ejohn.org/blog/versions-of-javascript/"&gt;isn&amp;#39;t implemented in all browsers&lt;/a&gt;
(actually, IE seems to be the real problem here).
&lt;/p&gt;
&lt;p&gt;
Anyway, thanks to the awesomeness of dynamic typing and
&lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/06/12/javascript-not-your-father-s-inheritance-model-part-2.aspx"&gt;prototypeal inheritance&lt;/a&gt;
in JavaScript, we can fix that ourselves with code similar to the below. 
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(item) {
    // implementation goes here
  };
}&lt;/pre&gt;

&lt;p&gt;&lt;i&gt;Actually, if you&amp;#39;re just looking for the final solution you can
find it easily with your search engine of choice or skip to the 
&lt;a&gt;bottom of this article&lt;/a&gt;.&lt;/i&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
But, instead of going through the normal trial and error approach,
I chose to flex my TDD muscle and try to create this method using
a test-first routine. For this exercise, I chose 
&lt;a href="http://docs.jquery.com/QUnit"&gt;QUnit&lt;/a&gt; as the unit testing framework.
&lt;/p&gt;
&lt;p&gt;
I started with a standard empty testing HTML file where I&amp;#39;ll put my test cases and
a reference to my-library.js where I&amp;#39;ll add this new method. 
&lt;/p&gt;

&lt;pre name="code" class="html:nogutter"&gt;&amp;lt;html&amp;amp;gt
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Tests for mylibrary.js&amp;lt;/title&amp;gt;
    &amp;lt;link href=&amp;quot;testsuite.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; /&amp;gt;
    &amp;lt;script src=&amp;quot;jquery.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;testrunner.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;my-library.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Tests for mylibrary.js&amp;lt;/h1&amp;gt;
    &amp;lt;h2 id=&amp;quot;banner&amp;quot;&amp;gt;
      &amp;lt;span style=&amp;quot;color:#fff;&amp;quot;&amp;gt;Result: Red/Green?&amp;lt;/span&amp;gt;
    &amp;lt;/h2&amp;gt;
    &amp;lt;h2 id=&amp;quot;userAgent&amp;quot;&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;ol id=&amp;quot;tests&amp;quot;&amp;gt;&amp;lt;/ol&amp;gt;
     &amp;lt;!--
        The #main element is like your test fixture. It&amp;#39;s like the 
		data for your tests.     
        Whatever exists inside the #main element gets restored 
        before each test.
        Feel free to manipulate the contents of #main in your tests.
      --&amp;gt;
    &amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;

&lt;p&gt;
You can put your test cases in a separate .js file and reference it here but
I&amp;#39;ll just add the necessary JavaScript to the HTML file itself in this exercise.
&lt;/p&gt;
&lt;p&gt;
Here are the test cases I&amp;#39;m going to support:
&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Missing items return -1&lt;/li&gt;
	&lt;li&gt;Existing item is found&lt;/li&gt;
	&lt;li&gt;Existing item is found with positive starting index&lt;/li&gt;
	&lt;li&gt;Existing item is not found with positive starting index&lt;/li&gt;
	&lt;li&gt;Existing item is found with negative starting index&lt;/li&gt;
	&lt;li&gt;Existing item is not found with negative starting index&lt;/li&gt;
	&lt;li&gt;Comparison is non-coercive&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Let&amp;#39;s start with the first test: &lt;i&gt;Missing items return -1&lt;/i&gt;. It&amp;#39;s a simple value comparison.
At this point I do not have anything written yet for the &lt;code&gt;indexOf&lt;/code&gt; function,
it doesn&amp;#39;t even exist if you&amp;#39;re on IE. Add the following to the HTML file.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;$(function() {
  var list = [11, 22, 33, 44];
  
  module(&amp;#39;Array.indexOf&amp;#39;);
  
  test(&amp;#39;Missing items return -1&amp;#39;, function() {
    equals(list.indexOf(1234), -1);
  });

});&lt;/pre&gt;                

&lt;p&gt;
When you open the HTML file on IE (I&amp;#39;m using IE8), you&amp;#39;ll see this:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_1.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
Totally expected, but let&amp;#39;s try to make this test pass. In the my-library.js file,
let&amp;#39;s add the simplest code that can satisfy that test.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function() {
      return -1;
    };
}&lt;/pre&gt;

&lt;p&gt;
The outer &lt;code&gt;if&lt;/code&gt; is there just to prevent replacing the function if
it already exists. The function is clearly incomplete, but that&amp;#39;s not the point.
The point is that it passes the test:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_2.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
Great. Time for the second test: &lt;i&gt;Existing item is found&lt;/i&gt;. For that one
we will need to loop through the items in the array. The array is &lt;code&gt;this&lt;/code&gt;
in the method. Here&amp;#39;s the test, which we add right after the first one.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;test(&amp;#39;Existing item is found&amp;#39;, function() {
  equals(list.indexOf(22), 1);
});&lt;/pre&gt;

&lt;p&gt;And of course that fails&lt;/p&gt;

&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_3.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
Time to make it pass.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(item) {
    for (var i=0; i&amp;lt;this.length; i++) {
      if (this[i] == item) {
        return i;
      }
    }
    return -1;
  };
}&lt;/pre&gt;
		
&lt;p&gt;
And it passes:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_4.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
Now let&amp;#39;s tackle the third test case: &lt;i&gt;Existing item is found with positive starting index&lt;/i&gt;.
This one starts to make things interesting. Here&amp;#39;s the test.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;test(&amp;#39;Existing item is found with positive starting index&amp;#39;, function() {
  //let&amp;#39;s try a few boundary conditions
  equals(list.indexOf(33, 0), 2);
  equals(list.indexOf(33, 1), 2);
  equals(list.indexOf(33, 2), 2);
});&lt;/pre&gt;

&lt;p&gt;
Hmmm. The test passes, as we can see below. Well, that was kind of an accident but 
I&amp;#39;ll leave the test as is because it does test what was specified. Leaving the
test will help us if we make changes that break this specification.
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_5.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
The next test case is &lt;i&gt;Existing item is not found with positive starting index&lt;/i&gt;. We could 
write it like this:
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;test(&amp;#39;Existing item is not found with positive starting index&amp;#39;, function() {
  equals(list.indexOf(33, 3), -1);
  equals(list.indexOf(33, 1000), -1);
});&lt;/pre&gt;

&lt;p&gt;
And boom! It fails. It should, we don&amp;#39;t even have support for that second parameter yet.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_6.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
Failing it is, pass it we must. First attempt:
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(item, startIndex) {
    for (var i=startIndex; i&amp;lt;this.length; i++) {
      if (this[i] == item) {
        return i;
      }
    }
    return -1;
  };
}&lt;/pre&gt;

&lt;p&gt;
It passes the new test, but it fails another one:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_7.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
That&amp;#39;s actually pretty cool. We would have created a mess if we had just
added the second parameter without some regression testing. Hooray for
unit tests! 
&lt;/p&gt;
&lt;p&gt;
What&amp;#39;s happening is that my &lt;code&gt;startIndex&lt;/code&gt; defaults to &lt;code&gt;undefined&lt;/code&gt;
if not passed by the caller. It should default to zero. Easy fix.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(item, startIndex) {
    startIndex = startIndex || 0;
    for (var i=startIndex; i&amp;lt;this.length; i++) {
      if (this[i] == item) {
        return i;
      }
    }
    return -1;
  };
}&lt;/pre&gt;	

&lt;p&gt;
I see the green light!
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_8.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
Our next test case is up: &lt;i&gt;Existing item is found with negative starting index&lt;/i&gt;.
What we are trying to do here is allow the caller to specify the starting position as
an offset from the last item using a negative number. So in a 4-element array, passing
-1 means that we start at the last item and passing -3 we start at the second item. See 
the test.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;test(&amp;#39;Existing item is found with negative starting index&amp;#39;, function() {
  equals(list.indexOf(33, -2), 2);
  equals(list.indexOf(33, -3), 2);
  equals(list.indexOf(33, -1000), 2);
});&lt;/pre&gt;

&lt;p&gt;
Once again it passes by accident. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_9.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
The next text case will show that it was an accident:
&lt;i&gt;Existing item is not found with negative starting index&lt;/i&gt;. The test for that is below:
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;test(&amp;#39;Existing item is not found with negative starting index&amp;#39;, function() {
  equals(list.indexOf(33, -1), -1);
  equals(list.indexOf(11, -3), -1);
});&lt;/pre&gt;


&lt;p&gt;
It fails:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_10.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
Making it pass is not that hard, we just need to compute a positive 
version of that negative start index.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(item, startIndex) {
    startIndex = startIndex || 0;
    
    if (startIndex &amp;lt; 0) {
      startIndex += this.length;
    }
    
    for (var i=startIndex; i&amp;lt;this.length; i++) {
      if (this[i] == item) {
        return i;
      }
    }
    return -1;
  };
}&lt;/pre&gt;	

&lt;p&gt;	
Ding, ding, ding! Another passing test for our team.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_11.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
Lastly, we need to make sure that the &lt;i&gt;Comparison is non-coercive&lt;/i&gt;. By
that we mean, a number will never equal a string &amp;mdash; or generally speaking, the
things being compared must be of the same type. Let&amp;#39;s get some tests that
try to point out tha flaw in our current code.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;test(&amp;#39;Comparison is non-coercive&amp;#39;, function() {
  equals(list.indexOf(&amp;#39;22&amp;#39;), -1);
});&lt;/pre&gt;

&lt;p&gt;
This fails because, strictly speaking, &lt;code&gt;22&lt;/code&gt; and &lt;code&gt;&amp;#39;22&amp;#39;&lt;/code&gt;
are two different things and we didn&amp;#39;t want to match that element like we did.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_12.png" alt="" /&gt;
&lt;/p&gt;

&lt;p&gt;
	On to the fix. Can you spot the difference? Try harder.
&lt;/p&gt;
&lt;a name="solution"&gt;&lt;/a&gt;
&lt;pre name="code" class="js:nogutter"&gt;if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(item, startIndex) {
    startIndex = startIndex || 0;
    
    if (startIndex &amp;lt; 0) {
        startIndex += this.length;
    }
    
    for (var i=startIndex; i&amp;lt;this.length; i++) {
        if (this[i] === item) {
          return i;
        }
    }
    return -1;
  };
}&lt;/pre&gt;	

&lt;p&gt;
And here is the QUnit report in all its successful glory.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/tdd_2D00_qunit_2D00_13.png" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;
If you&amp;#39;ve never been exposed to TDD this may have felt awkward but
hopefully you noticed that it&amp;#39;s more of an evolutionary design
approach, as opposed to trying to make it perfect on the first attempt or
even reckless patching.
&lt;/p&gt;
&lt;p&gt;
It also left us with a valuable collection of tests that we
can execute after making changes to the code, ensuring we didn&amp;#39;t
break anything by accident.
&lt;p&gt;	

&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53698" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="Development" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Development/default.aspx" /><category term="JavaScript" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx" /><category term="UnitTesting" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/UnitTesting/default.aspx" /></entry><entry><title>Talk: Stop Programming JavaScript by Luck</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2009/11/10/talk-stop-programming-javascript-by-luck.aspx" /><id>/blogs/sergio_pereira/archive/2009/11/10/talk-stop-programming-javascript-by-luck.aspx</id><published>2009-11-10T09:07:00Z</published><updated>2009-11-10T09:07:00Z</updated><content type="html">&lt;p&gt;
	Last Saturday I had the pleasure to present a JavaScript talk at the 
	&lt;a href="http://iowacodecamp.com/"&gt;Iowa Code Camp&lt;/a&gt;. The talk was
	&lt;i&gt;&lt;a href="http://www.sergiopereira.com/presentations/js-by-luck.html"&gt;Stop Programming JavaScript By Luck&lt;/a&gt;&lt;/i&gt; and it tries to
	highlight some of the most puzzling differences from your mainstream
	programming language (read: C#, VB, Java.)
&lt;/p&gt;
&lt;p&gt;
	I&amp;#39;d like to thank all that came to the talk and the Code Camp organizers
	for inviting me. Here are the video recording and the slide deck.
&lt;/p&gt;

&lt;h3&gt;The video&lt;/h3&gt;
&lt;object width="545" height="349" id="viddler_2cc7bbee"&gt;&lt;param name="movie" value="http://www.viddler.com/player/2cc7bbee/" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed src="http://www.viddler.com/player/2cc7bbee/" width="545" height="349" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" name="viddler_2cc7bbee"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;And the slide deck.&lt;/h3&gt;

&lt;div style="width:425px;text-align:left;" id="__ss_2459675"&gt;	
	
	&lt;object style="margin:0px;" width="425" height="355"&gt;
		&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=js-by-luck-091109125553-phpapp02&amp;amp;stripped_title=stop-programming-in-javascript-by-luck" /&gt;
		&lt;param name="allowFullScreen" value="true" /&gt;
		&lt;param name="allowScriptAccess" value="always" /&gt;
		&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=js-by-luck-091109125553-phpapp02&amp;amp;stripped_title=stop-programming-in-javascript-by-luck" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;
		&lt;/embed&gt;
	&lt;/object&gt;

&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53615" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="JavaScript" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx" /><category term="Video" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Video/default.aspx" /><category term="Community" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/Community/default.aspx" /></entry><entry><title>LG BD390 Blu-ray player and D-Link DIR 655 Router: not friends</title><link rel="alternate" type="text/html" href="/blogs/sergio_pereira/archive/2009/11/04/lg-bd390-blu-ray-player-and-d-link-dir-655-router-not-friends.aspx" /><id>/blogs/sergio_pereira/archive/2009/11/04/lg-bd390-blu-ray-player-and-d-link-dir-655-router-not-friends.aspx</id><published>2009-11-05T00:33:00Z</published><updated>2009-11-05T00:33:00Z</updated><content type="html">	&lt;p&gt;A month or so ago I bought a Blu-ray player. I waited a bit to buy one of those because,
	frankly speaking, the improved image quality and any bonus features in the discs weren&amp;#39;t
	attractive enough for me to replace the DVD player.&lt;/p&gt;

	&lt;p&gt;I also wanted a networked player that could stream movies from my 
	&lt;a href="http://www.netflix.com"&gt;Netflix&lt;/a&gt; queue. To make matters worse,
	running a CAT-5 cable from my basement (where my wireless router lives) to 
	the bedroom (the BR player&amp;#39;s final destination) wasn&amp;#39;t really something I was 
	looking forward to.&lt;/p&gt;
	
	&lt;p&gt;
	&lt;a href="http://www.amazon.com/dp/B001UQ6F5M?tag=by-asin-tag-20"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/brplayer.png" align="right" border="0" alt="" /&gt;&lt;/a&gt;
	That&amp;#39;s when I did some shopping around and came across the 
	&lt;a href="http://www.amazon.com/dp/B001UQ6F5M?tag=by-asin-tag-20"&gt;LG BD390&lt;/a&gt; 
	Wi-Fi-enabled Blu-ray player. It supports wireless 802.11n and access to a few online
	services like YouTube, Netflix and &lt;a href="http://www.vudu.com/"&gt;VUDU&lt;/a&gt;. It can
	also find media in my home network.&lt;/p&gt;

	&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; I know there&amp;#39;s always someone that will come suggest taking a look at the
	PS3 or XBOX can do some or all of that. I&amp;#39;m not a gamer so I didn&amp;#39;t want to
	have a gaming console in my bedroom and deal with issues related to 
	the &lt;i&gt;not being a simple player&lt;/i&gt; aspects of the device (like maybe having
	to buy extra adapters/connectors, remote control, and what-have-you). It&amp;#39;s
	probably a no-brainer if you&amp;#39;re into video games. Did I say I do not buy Sony?&lt;/p&gt;

	&lt;h3&gt;Welcome LG BD390&lt;/h3&gt;

	&lt;p&gt;So I went and bought the LG BD390 and installed it where it was supposed to be. I
	was a little worried about not having the 802.11n router setup yet (it was still
	on its way) but I decided to give it a shot even on my 5-year old 802.11g router. 
	I thought maybe I wouldn&amp;#39;t get HD streaming or choppy video, but at least I would
	get a feeling about the device&amp;#39;s capabilities while I waited for the new router to 
	arrive.&lt;/p&gt;

	&lt;h3&gt;Works great on wireless-G&lt;/h3&gt;

	&lt;p&gt;To my surprise, the LG BD390 worked great over wireless-G. Setup is incredibly easy
	(the only hard part was really entering the long WPA password using the on-screen
	keyboard.) It boots up fast. Within 5 minutes from its first power-on it had
	already found and updated its firmware, I had activated my Netflix streaming
	and The Office was streaming in HD on my TV.&lt;/p&gt;

	&lt;p&gt;Best gadget purchase in years. This device will definitely change the way I watch movies and 
	TV series, and listen to music (BTW, since it&amp;#39;s easy to upgrade the firmware and
	other LG products offer Pandora, here&amp;#39;s to hoping the BD390 gets that too soon.)&lt;/p&gt;

	&lt;h3&gt;But not so fast. Bad wireless-N surprise.&lt;/h3&gt;

	&lt;p&gt;You&amp;#39;d think that by upgrading my network to wireless-N would only make the
	whole experience much better, right? Me too.&lt;/p&gt;

	&lt;p&gt;
	&lt;a href="http://www.amazon.com/dp/B000LIFB7S?tag=by-asin-tag-20"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.11/router.png" align="left" border="0" style="margin-right:10px;" alt="" /&gt;&lt;/a&gt;
	I upgraded my trusty wireless-G router with a shiny new D-Link
	&lt;a href="http://www.amazon.com/dp/B000LIFB7S?tag=by-asin-tag-20"&gt;DIR 655&lt;/a&gt; 
	wireless-N Gigabit model. It has some interesting features, USB port, decent 
	firmware features (well, read on,) and seems rather popular anyway.&lt;/p&gt;

	&lt;p&gt;Once I configured it to the exact same network settings as the previous router, I
	checked the laptops were working fine with it and went straight to enjoy some more
	streaming on my Blur-ray player. I immediately noticed that the signal strength had
	dropped from 5 bars to 2, 1, and sometimes no bars at all. Even when a couple of bars 
	were there, it wouldn&amp;#39;t even browse my local network.&lt;/p&gt;

	&lt;p&gt;I even tried using a &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16833166042"&gt;cheap-o router&lt;/a&gt; 
	in repeater mode but it didn&amp;#39;t play well with my D-Link router and even the laptops
	would lose connectivity at random when this thing was active &amp;mdash; I ended up
	returning it.
	&lt;/p&gt;

	&lt;p&gt;A month later (and a few lost frustrating hours) later I came across 
	&lt;a href="http://www.amazon.com/review/R4XT8B6JVOZ58/ref=cm_srch_res_rtr_alt_1"&gt;this post&lt;/a&gt;
	on the Amazon reviews for the player. Basically, even though there was a new firmware available,
	the router insisted in telling me it had the latest one. And it just so happens that the
	firmware it had (v1.2) had some serious bugs. Short version, many times it would not work
	at all with the Blu-ray player.&lt;/p&gt;

	&lt;p&gt;I followed the suggested instructions and things are much better now. I still get a very
	weak signal but at least I&amp;#39;m able to consistently stream HD content. I hope the
	next version of the BD390 comes with an external antenna. I might try another
	router and see if they have a stronger signal &amp;mdash; this seems to be a common
	complaint about this D-Link model.&lt;/p&gt;

	&lt;p&gt;So if you&amp;#39;re in the market for a Blu-ray player I can recommend LG&amp;#39;s BD390
	but I&amp;#39;d suggest you search the web for any issues with your wireless-N router
	(unless you&amp;#39;re planning to wire it up, in that case I recommended it 100%).
	If you&amp;#39;re buying your router together with the BR player, buy it from a store
	that you can easily return it in case it doesn&amp;#39;t work well with the BR player.
	On the other hand, if you&amp;#39;re looking for a new router, I cannot recommend 
	D-Link&amp;#39;s DIR 655.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53383" width="1" height="1"&gt;</content><author><name>sergiopereira</name><uri>http://devlicio.us/members/sergiopereira/default.aspx</uri></author><category term="review" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/review/default.aspx" /><category term="gadgets" scheme="http://devlicio.us/blogs/sergio_pereira/archive/tags/gadgets/default.aspx" /></entry></feed>