<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicious.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Sergio Pereira : Development</title><link>http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx</link><description>Tags: Development</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>More on blocked files</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2010/06/23/more-on-blocked-files.aspx</link><pubDate>Thu, 24 Jun 2010 03:26:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:60722</guid><dc:creator>sergiopereira</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=60722</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2010/06/23/more-on-blocked-files.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve &lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/04/03/blocked-js-files-keep-biting-me.aspx"&gt;written about this&lt;/a&gt; before.
You download a file to use in your web application, like a JavaScript library or an image file
but the browser just can&amp;#39;t seem to load it. You spend hours looking for a typo or broken link
until you find out about that Unblock button and you realize that it&amp;#39;s IIS that isn&amp;#39;t serving 
the file. The file had been there; you had the correct URL all along; it&amp;#39;s just disallowed.
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/properties_5F00_js.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/properties_5F00_js_5F00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I actually developed the reflex to right click and unblock each an every file I
download now. It&amp;#39;s stupid, isn&amp;#39;t it? I should have imagined there was a way to 
disable that Windows feature instead of just learning how to live with the problem.
&lt;/p&gt;
&lt;p&gt;Well, no more. Here&amp;#39;s how you can disable it. Credit goes to &lt;a href="http://www.petri.co.il/unblock-files-windows-vista.htm"&gt;this article&lt;/a&gt;.
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Run &lt;b&gt;gpedit.msc&lt;/b&gt; (the group policy editor)&lt;/li&gt;
	&lt;li&gt;Go to &lt;b&gt;User Configuration/Administrative Templates/Windows Components/Attachment Manager&lt;/b&gt;&lt;/li&gt;
	&lt;li&gt;Find the setting named &lt;b&gt;Do not preserve zone information in file attachments&lt;/b&gt; and &lt;b&gt;enable&lt;/b&gt; it&lt;/li&gt;
	&lt;li&gt;Log off then log back on, or update the current policies with: &lt;b&gt;Gpupdate /force&lt;/b&gt; in any command prompt.
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.06/unblock.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2010.06/unblock_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; If you&amp;#39;re using Chrome it looks like &lt;a href="http://codereview.chromium.org/590001"&gt;there&amp;#39;s some bug&lt;/a&gt; that may or may not be
taken care of as you read this. Chrome doesn&amp;#39;t seem to honor the policy setting and always mark the downloaded files as unsafe.&lt;/p&gt;

&lt;p&gt;Now I just need to add this to the list of tasks anytime I get a new machine or repave one of them.&lt;/p&gt;

&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=60722" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category></item><item><title>The Ground is Shaking Again. Get Mobile.</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2010/06/17/the-ground-is-shaking-again-get-mobile.aspx</link><pubDate>Thu, 17 Jun 2010 05:08:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:60619</guid><dc:creator>sergiopereira</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=60619</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2010/06/17/the-ground-is-shaking-again-get-mobile.aspx#comments</comments><description>&lt;p&gt;A little over two years ago I commented how surprising it was that
&lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2008/05/18/and-the-winner-is-vb-net.aspx"&gt;VisualBasic 
was still more popular than C#&lt;/a&gt; in the .Net world. Back 
then I checked the &lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;TIOBE Index&lt;/a&gt; 
and saw that VB (in all its flavors) enjoyed almost 11% of relevance 
while C# wasn&amp;#39;t even at the 4% level.&lt;/p&gt;

&lt;p&gt;When we look at the June 2010 rank below we see that C# has finally
caught up with VB, and it&amp;#39;s safe to say C# is now the
most popular .Net language (remember, the VB index is not made up of just VB.NET.)&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Java&lt;/td&gt;&lt;td&gt;18.03%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:18.03%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;C&lt;/td&gt;&lt;td&gt;17.81%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:17.81%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;C++&lt;/td&gt;&lt;td&gt;10.76%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:10.76%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;PHP&lt;/td&gt;&lt;td&gt;8.93%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:8.93%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;(Visual) Basic&lt;/td&gt;&lt;td&gt;5.87%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:5.87%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;C#&lt;/td&gt;&lt;td&gt;5.20%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:5.20%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Python&lt;/td&gt;&lt;td&gt;4.27%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:4.27%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Perl&lt;/td&gt;&lt;td&gt;3.20%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:3.20%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Objective-C&lt;/td&gt;&lt;td&gt;2.47%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:2.47%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Delphi&lt;/td&gt;&lt;td&gt;2.39%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:2.39%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;JavaScript&lt;/td&gt;&lt;td&gt;2.19%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:2.19%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Ruby&lt;/td&gt;&lt;td&gt;2.07%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:2.07%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;PL/SQL&lt;/td&gt;&lt;td&gt;0.79%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.79%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;SAS&lt;/td&gt;&lt;td&gt;0.70%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.70%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Pascal&lt;/td&gt;&lt;td&gt;0.70%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.70%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Lisp/Scheme/Clojure&lt;/td&gt;&lt;td&gt;0.65%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.65%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Lua&lt;/td&gt;&lt;td&gt;0.59%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.59%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;18&lt;/td&gt;&lt;td&gt;MATLAB&lt;/td&gt;&lt;td&gt;0.59%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.59%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;19&lt;/td&gt;&lt;td&gt;ABAP&lt;/td&gt;&lt;td&gt;0.58%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.58%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;tr&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;PowerShell&lt;/td&gt;&lt;td&gt;0.53%&lt;/td&gt;&lt;td style="width:300px;"&gt;&lt;div style="background-color:blue;width:0.53%;"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;
&lt;/table&gt;

&lt;p&gt;Again, anyone can debate the importance of this ranking system, but at least it
has been there for a while and to me it seems to represent the
pulse of software development quite well.&lt;/p&gt;

&lt;h3&gt;Movers and shakers&lt;/h3&gt;

&lt;p&gt;But this post is not about C# vs. VB.NET.&lt;/p&gt;

&lt;p&gt;This time around what caught my attention was the &lt;b&gt;impressive
rise of  Objective-C&lt;/b&gt; (up 36 positions in one year). Now,
no matter how more common Macs have become in the last few years,
no one will convince me this increase in Objective-C is due to
native OSX application development :)&lt;/p&gt;

&lt;p&gt;Of course we all know it&amp;#39;s caused by the surge in mobile and device app
development (iPhone, iPad, and anything that they decide will
run the iOS, like the AppleTV in the future, who knows?)&lt;/p&gt;

&lt;p&gt;If you look at the trending chart on the 
&lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;TIOBE page&lt;/a&gt;
you&amp;#39;ll see that Objective-C started to gain significant steam around June of
last year, coincidentally (maybe not?) when the iPhone 3GS was announced.&lt;/p&gt; 

&lt;h3&gt;Keep your eyes on the ball&lt;/h3&gt; 

&lt;p&gt;Are you playing with Mobile yet? Have you:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Started reading about mobile development?&lt;/li&gt;
&lt;li&gt;Developed a Mobile web site?&lt;/li&gt;
&lt;li&gt;Written and tested a native app against a device emulator/VM (iPhone, Android, WebOS, WP7)?&lt;/li&gt;
&lt;li&gt;Written and deployed an app to your own mobile device?&lt;/li&gt;
&lt;li&gt;Published an app on the market?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It&amp;#39;s not like you will find yourself out of a job if you don&amp;#39;t get into mobile
but for many developers, from software shops to corporate environments, sooner
or later a request for a mobile product or a mobile version of an existing
one will swing by your desk.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s an exciting time. Once again you have the chance of taking the lead
and play an important role in your team by staying ahead of the game. 
Remember when you started seeing request for Ajax and fancy UI&amp;#39;s in
your web applications. Remember how you were one of the few that
knew anything about it in your team? Same thing here. Only much bigger.&lt;/p&gt;

&lt;h3&gt;What I&amp;#39;m looking into&lt;/h3&gt;

&lt;p&gt;There are two different fronts that interest me in mobile development: 
Native Android apps and Mobile Sites. I&amp;#39;ll explain.&lt;/p&gt;

&lt;p&gt;The time I spent in Objective-C and XCode in the past was enough for
me to know I&amp;#39;d be grinding my teeth and blowing off steam every single
day if I wanted to develop for the iPhone (it&amp;#39;s probably just me, I can live with that admission.)
Besides, I don&amp;#39;t like the idea of an approval process before I can give away or sell my apps.&lt;/p&gt;

&lt;p&gt;Windows Phone is something that I&amp;#39;ll have to wait more and see what
kind of traction it gains. It also has the approval process issue. The
big plus will be the development tools, which I think will better than
iPhone and Android.&lt;/p&gt;

&lt;p&gt;All that, combined with the enormous momentum that Android has, made
me start coding for Android when it comes to native apps.&lt;/p&gt;

&lt;h3&gt;Don&amp;#39;t forget Mobile Web&lt;/h3&gt;

&lt;p&gt;Native mobile development is fun and rewarding but let&amp;#39;s not kid ourselves.
History shows that businesses will favor the simplicity of web development.&lt;/p&gt;

&lt;p&gt;I went through that transition period when custom desktop application
development quickly lost market to web applications. And that happened
in a world where Windows was virtually in every workstation that mattered.&lt;/p&gt;

&lt;p&gt;Now imagine the mobile scene, where there&amp;#39;s more than one big player, none
equivalent to what Windows was back in 1998. Do you really think anyone
will want incur the cost of maintaining 3 or 4 different native 
versions of each mobile application that we will start cranking out
like we do web apps today? Native apps will probably be the minority,
for environments where you have the luxury of dictating your end-user&amp;#39;s
choice of mobile device.&lt;/p&gt;

&lt;p&gt;Didn&amp;#39;t we just spend the better part of the last 10 years trying to get out of 
a certain single-browser paradigm? Do we want to repeat that mistake?&lt;/p&gt;

&lt;h3&gt;Moving to HTML5&lt;/h3&gt;

&lt;p&gt;Why is HTML5 so important in Mobile and not as much in the standard Web yet? Well,
for one there is a greater percentage of HTML5-capable browsers in Mobile
than on the desktop browsers. Android, iPhone, WebOS (and soon BlackBerries) 
have WebKit browsers. &lt;/p&gt;

&lt;p&gt;With things like richer forms, offline support, canvas, video and the
Geo-Location API (not really HTML5 but present in those WebKit browsers) we
can build really capable mobile web apps. Not just small screen
versions of the regular web apps.&lt;/p&gt;

&lt;p&gt;To be very straight forward about it, the way I personally see it is
that HTML5 is where the bulk of the mobile development will happen in the Enterprise and
consumer-facing applications.&lt;/p&gt;

&lt;p&gt;Maybe something like Flash, AIR, or Silverlight makes a run for their
mobile money too but with all the bullying from Apple and diverging
opinions everywhere, that&amp;#39;s not something I&amp;#39;m spending time on right now.&lt;/p&gt;

&lt;h3&gt;Native or Web?&lt;/h3&gt;

&lt;p&gt;Both. But definitely much more of the Web kind.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=60619" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Mobile/default.aspx">Mobile</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Android/default.aspx">Android</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/HTML5/default.aspx">HTML5</category></item><item><title>Oh, no. My TortoiseSVN overlays are missing</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2010/01/05/oh-no-my-tortoisesvn-overlays-are-missing.aspx</link><pubDate>Tue, 05 Jan 2010 09:13:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54881</guid><dc:creator>sergiopereira</dc:creator><slash:comments>19</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=54881</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2010/01/05/oh-no-my-tortoisesvn-overlays-are-missing.aspx#comments</comments><description>	&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://devlicious.com/aggbug.aspx?PostID=54881" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category></item><item><title>Test-Driving a new feature for JavaScript</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/11/12/test-driving-a-new-feature-for-javascript.aspx</link><pubDate>Fri, 13 Nov 2009 01:16:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53698</guid><dc:creator>sergiopereira</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=53698</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/11/12/test-driving-a-new-feature-for-javascript.aspx#comments</comments><description>&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://devlicious.com/aggbug.aspx?PostID=53698" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/UnitTesting/default.aspx">UnitTesting</category></item><item><title>IE6 still haunts me</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/10/21/ie6-still-haunts-me.aspx</link><pubDate>Wed, 21 Oct 2009 22:16:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:52894</guid><dc:creator>sergiopereira</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=52894</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/10/21/ie6-still-haunts-me.aspx#comments</comments><description>&lt;p&gt;Oh, the woes of supporting IE6 (or, better put, IE666 &amp;mdash; the browser of the beast.)&lt;/p&gt;

&lt;p&gt;
	Halloween is definitely upon us. Today I spent a good chunk of time trying to identify the source of a problem in
	my application. Right now I&amp;#39;m in the process of jQuery-fying some legacy JavaScript,
	which includes Ajax calls and error handling logic.
&lt;/p&gt;
&lt;p&gt;
	At some point I needed to pop-up a DIV that was supposed to look like a modal message box,
	reporting some error that happened during the Ajax call. That was not hard at all. I used
	the &lt;a href="http://www.ericmmartin.com/projects/simplemodal/"&gt;SimpleModal&lt;/a&gt; plugin and
	got the message box up in not time at all.
&lt;/p&gt;
&lt;h3&gt;Not so fast, you have IE6 users&lt;/h3&gt;
&lt;p&gt;
	As with many web developers out there, I don&amp;#39;t have the luxury of ignoring IE6 users because
	they are upwards of 60% of our user base (corporate users that for some reason can&amp;#39;t easily
	upgrade their browsers.)
&lt;/p&gt;
&lt;p&gt;
	I thought it wouldn&amp;#39;t be a problem because the SimpleModal plugin handles a number of IE6 issues,
	including the insertion of an &lt;code&gt;IFrame&lt;/code&gt; to overcome the bleedthrough of &lt;code&gt;Select&lt;/code&gt; tags.
	But of course it couldn&amp;#39;t be that easy right?
&lt;/p&gt;
&lt;p&gt;
In some of my tests IE6 was simply &lt;b&gt;crashing&lt;/b&gt; when I tried to open the &amp;quot;modal&amp;quot; message. After a lot or hair 
pulling, I saw this suspicious HTML in one of my messages:
&lt;/p&gt;
&lt;pre name="code" class="html"&gt;&amp;lt;table style=&amp;quot;font-size: expression(parentnode.currentstyle.fontsize);&amp;quot; &amp;gt;
    &amp;lt;!-- rest of the table is normal --&amp;gt;
&amp;lt;/table&amp;gt;&lt;/pre&gt;

&lt;p&gt;
	Sure enough, moving that &lt;i&gt;hack&lt;/i&gt; to a proper CSS rule in the external .css file made the error go away.
	We shouldn&amp;#39;t be using dynamic CSS expressions anyway, since 
	&lt;a href="http://blogs.msdn.com/ie/archive/2008/10/16/ending-expressions.aspx"&gt;they were removed from IE8&lt;/a&gt;, 
	so I went ahead and ditched that kind of usage wherever I could find it.
&lt;/p&gt;

&lt;p&gt;This is just to keep us on our toes regarding IE6 support. Even though the modern JavaScript libraries go
to great lengths to support IE6 and make our coding transparent, nothing substitutes good old manual testing
to make sure IE6 doesn&amp;#39;t play pranks on us in production.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=52894" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category></item><item><title>JavaScript and its love for zeroes</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/09/19/javascript-and-its-love-for-zeroes.aspx</link><pubDate>Sat, 19 Sep 2009 13:54:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:51520</guid><dc:creator>sergiopereira</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=51520</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/09/19/javascript-and-its-love-for-zeroes.aspx#comments</comments><description>&lt;div class="note"&gt;
	This post is part of a series called &lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/tags/JavaScript-Demystified/default.aspx"&gt;
	JavaScript Demystified&lt;/a&gt;.
&lt;/div&gt;

&lt;p&gt;Answer quick. Do you know what date is being created here?&lt;/p&gt;
&lt;pre name="code" class="js:nogutter"&gt;var year = &amp;#39;2009&amp;#39;, month = &amp;#39;09&amp;#39;, day = &amp;#39;01&amp;#39;;
var date = new Date( 
             parseInt(year),
			 parseInt(month),
			 parseInt(day)
			 );	&lt;/pre&gt;

&lt;p&gt;
At first glance, it wouldn&amp;#39;t surprising that someone guesseed &lt;i&gt;September 1&lt;sup&gt;st&lt;/sup&gt; 2009&lt;/i&gt;.
However, I&amp;#39;d not be writing this post if that was the correct answer, right?
&lt;/p&gt;
&lt;p&gt;
There&amp;#39;s an interesting and tricky thing with the JavaScript &lt;code&gt;parseInt&lt;/code&gt; function: it
can parse strings with a numeric value in the decimal radix, but also in other radices. See the
following examples.
&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;//passing the radix explicitly
parseInt(&amp;#39;1011&amp;#39;, 10); // ==&amp;gt; 1011
parseInt(&amp;#39;1011&amp;#39;,  2); // ==&amp;gt; 11
parseInt(&amp;#39;1011&amp;#39;,  8); // ==&amp;gt; 521
parseInt(&amp;#39;1011&amp;#39;, 16); // ==&amp;gt; 4113
&lt;/pre&gt;

&lt;p&gt;Maybe you thought that if you didn&amp;#39;t pass the radix, then it would default to 10 because
it&amp;#39;s the obvious behavior. Well, no. In JavaScript the default behavior is to try to
identify one of the literal formats and interpret that. So here&amp;#39;s that in action:&lt;/p&gt;

&lt;pre name="code" class="js:nogutter"&gt;//leaving JavaScript on its own
parseInt(&amp;#39;1011&amp;#39;); // ==&amp;gt; 1011 (decimal literal)
parseInt(&amp;#39;0x12&amp;#39;); // ==&amp;gt; 18   (hexadecimal literal)
parseInt(&amp;#39;0511&amp;#39;); // ==&amp;gt; 329  (octal literal)
parseInt(&amp;#39;0182&amp;#39;); // ==&amp;gt; 1    (whaaaa?!?!)
&lt;/pre&gt;

&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.09/js_2D00_newyear.png" align="left" alt="" /&gt;

&lt;p&gt;
If you are familiar with the literal notation for integer numbers in JavaScript,
and after I explained the default behavior of &lt;code&gt;parseInt&lt;/code&gt;, then
you probaly understood the results shown above. Well, maybe the last one deserves 
some comments.
&lt;/p&gt;
&lt;p&gt;
When JavaScript is parsing the string, if it finds a digit (number or alpha) that is invalid
in the chosen radix, it stops right there and parses only the portion of the string that
comes before that digit. So, since we started &lt;code&gt;&amp;#39;0182&amp;#39;&lt;/code&gt; with a leading zero, the 
octal radix is assumed. Then, because &lt;b&gt;8&lt;/b&gt; is not a valid octal digit, only &lt;code&gt;&amp;#39;01&amp;#39;&lt;/code&gt;
will be parsed, which becomes &lt;b&gt;1&lt;/b&gt;.
&lt;/p&gt;

&lt;div class="note"&gt;&lt;span class="legend"&gt;Tip #1:&lt;/span&gt;
If there&amp;#39;s any chance the string value you plan to parse into an integer number has
a leading zero (or a less likely &lt;b&gt;0x&lt;/b&gt;,) then be safe and pass the radix parameter
to your &lt;code&gt;parseInt&lt;/code&gt; call. If you&amp;#39;re extra paranoid, then always pass the radix.
&lt;/div&gt;


&lt;h3&gt;Back to our original question&lt;/h3&gt;

&lt;p&gt;Armed with the clarification made above, we can expand our example like this:&lt;/p&gt;
&lt;pre name="code" class="js:nogutter"&gt;//given:
var year = &amp;#39;2009&amp;#39;, month = &amp;#39;09&amp;#39;, day = &amp;#39;01&amp;#39;;
// then the following statement:
var date = new Date( 
         parseInt(year),
         parseInt(month),
         parseInt(day)
         );	
//...is equivalent to:
var date = new Date( 
         2009,
         0,  // ===&amp;gt; oopsie
         1
         );	&lt;/pre&gt;

&lt;p&gt;Hmmm, a zero in the month parameter. Will we have an error here? No, here comes the second potential surprise of this post.&lt;/p&gt;

&lt;div class="note"&gt;&lt;span class="legend"&gt;Tip #2:&lt;/span&gt;
When creating a new date using &lt;code&gt;new Date(year, month, day)&lt;/code&gt;, the &lt;code&gt;month&lt;/code&gt;
parameter, and &lt;b&gt;only&lt;/b&gt; the month parameter is zero-based (0 to 11).
&lt;/div&gt;

&lt;p&gt;So, in case the tips and the picture in this text were not enough to help you guessing the
date being created, here goes another completely gratuitous one with the answer.

&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.09/js_2D00_newyear2.png" alt="" /&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=51520" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/JavaScript-Demystified/default.aspx">JavaScript-Demystified</category></item><item><title>Taming Firebug with Profiles</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/09/01/taming-firebug-with-profiles.aspx</link><pubDate>Tue, 01 Sep 2009 10:03:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:50941</guid><dc:creator>sergiopereira</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=50941</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/09/01/taming-firebug-with-profiles.aspx#comments</comments><description>	&lt;p&gt;
		This is a tip for anyone using Firefox and &lt;a href="http://getfirebug.com/" title="Firebug - Web Development Evolved"&gt;Firebug&lt;/a&gt; for web development
		that is not leveraging the Profiles feature of that browser. 
	&lt;/p&gt;
	&lt;p&gt;
		Recent versions of Firebug (after v1.3 I think) removed the ability to enable Firebug panes
		on a per-domain basis. Now it&amp;#39;s kind of all or nothing. And you know
		that you don&amp;#39;t want to have Firebug enabled when using Ajax-intensive
		applications like GMail, for example. 
	&lt;/p&gt;
	&lt;p&gt;
		The end result is that you are stuck in this annoying dance of of enabling/disabling,
		open/close Firebug when switching tabs.
	&lt;/p&gt;
	&lt;p&gt;
		There are some workarounds for that but I think the best solution for this problem
		is through &lt;a href="http://support.mozilla.com/en-US/kb/Profiles"&gt;Profiles&lt;/a&gt;, which is also a very nice approach for web development overall.
	&lt;/p&gt;
	
	&lt;h3&gt;Firefox Profiles&lt;/h3&gt;
	&lt;p&gt;
		Firefox stores all your preferences (add-ons, state, saved passwords, history, etc)
		inside profile directories. 
		It installs a default profile and that&amp;#39;s perfectly enough
		for the casual browser user. Web developers, add-on developers, and power users in
		general, on the other hand, can find handy uses for extra profiles.
	&lt;/p&gt;
	&lt;p&gt;
		You can see your profile directories in &lt;b&gt;%APPDATA%\Mozilla\Firefox\Profiles&lt;/b&gt;
		(or, on the Mac, &lt;b&gt;~/Library/Application Support/Firefox/Profiles&lt;/b&gt;).
	&lt;/p&gt;
	&lt;h3&gt;Development profile&lt;/h3&gt;
	&lt;p&gt;
		The suggestion I&amp;#39;m giving is to create a separate profile just to be used during web
		development work. That way you can exclude some of the add-ons (like ad blockers, 
		bookmarking extensions like Delicious, and any other non development-related extensions.)
		The opposite applies to your default profile &amp;mdash; you can now remove all the 
		development stuff from that profile and keep your browser a little lighter. In addition to that
                I use a different skin/theme in each profile, just to make it screaming obvious which one I&amp;#39;m 
                looking at.
	&lt;/p&gt;
	&lt;p&gt;
		Here&amp;#39;s how we create a new profile. First close all your Firefox windows and make sure 
		there&amp;#39;s no Firefox process running in the background. Now go to the command line 
		and enter this:
	&lt;/p&gt;
	&lt;pre&gt;(on Windows)
%ProgramFiles%\Mozilla Firefox\firefox.exe -ProfileManager
(or on the Mac)
/Applications/Firefox.app/Contents/MacOS/firefox -ProfileManager&lt;/pre&gt;
	
	&lt;p&gt;
		This will bring up the Profile Manager, where you can easily create a new
		profile. Create one named &lt;i&gt;Development&lt;/i&gt; and start it. 
	&lt;/p&gt;
&lt;p&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.09/profiles.png" alt="" /&gt;&lt;/p&gt;
	&lt;p&gt;
		Once started, you&amp;#39;ll notice that Firefox will open looking just like it did
		the first time you installed it. You can now install your favorite extensions
		for web development (like Firebug, &lt;a href="http://developer.yahoo.com/yslow/" title="Yahoo! YSlow for Firebug"&gt;YSlow&lt;/a&gt;, 
		&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/60"&gt;Web Developer Toolbar&lt;/a&gt;, 
		&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/59"&gt;User Agent Switcher&lt;/a&gt;,  etc)
	&lt;/p&gt;
	&lt;p&gt;
		To launch Firefox using the the Development profile you can create a shortcut
		that passes some arguments to Firefox, like &lt;b&gt;firefox.exe -P Development -no-remote&lt;/b&gt;.
		For example, I added that shortcut to my Desktop, Quick Launch, and Launchy. &lt;i&gt;(Firefox will
               remember which profile you started last using the Profile Manager, and use that one
               next time you start Firefox without explicitly choosing a profile. You may want to leave the default profile 
               selected in the Profile Manager.)&lt;/i&gt;
	&lt;/p&gt;
	
	&lt;h3&gt;More uses for Profiles&lt;/h3&gt;
	&lt;p&gt;
		Besides creating a profile dedicated to web development work, I can very well see
		myself eventually creating extra ones for different activities, like a &lt;i&gt;Presentation&lt;/i&gt; profile and
		a &lt;i&gt;NoAddons&lt;/i&gt; profile, for example. 
	&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=50941" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category></item><item><title>Circular Refactoring</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/08/14/circular-refactoring.aspx</link><pubDate>Fri, 14 Aug 2009 17:21:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:50065</guid><dc:creator>sergiopereira</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=50065</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/08/14/circular-refactoring.aspx#comments</comments><description>&lt;p&gt;One of these days I was chatting with &lt;a href="http://devlicio.us/blogs/Derik_whittaker/"&gt;Derik&lt;/a&gt; and we were
talking about refactoring and when to stop refactoring. We thought it
was funny (and embarrassing) how sometimes, after a few consecutive refactorings,
we are back at the starting point.&lt;/p&gt;

&lt;p&gt;This type of &lt;b&gt;Circular Refactoring&lt;/b&gt; is a real productivity enemy. In our
genuine desire to improve the code, and wishing to dive into an interesting task,
we sometimes lose sight of the code history and the real need for this change. It reminds 
me a lot of &lt;a href="http://stackoverflow.com/questions/184618/what-is-the-best-comment-in-source-code-you-have-ever-encountered/482129#482129"&gt;this funny comment&lt;/a&gt; (second part).&lt;/p&gt;

&lt;p&gt;How do you tell when you&amp;#39;re being a victim of this variation of the premature
optimization monster? Well, here&amp;#39;s a start:
&lt;/p&gt;

&lt;h3&gt;Top 10 signs you&amp;#39;ve fallen into circular refactoring&lt;/h3&gt;

&lt;div style="background-color:#eee;border:solid 1px #aaa;padding:4px;"&gt;
&lt;b&gt;
9 - Code gets eerily familiar by the minute.&lt;br /&gt;
8 - Your git repository doesn&amp;#39;t seem to grow.&lt;br /&gt;
7 - Work feels too much fun to be real.&lt;br /&gt;
6 - Your code metrics trending charts look like Bart Simpson&amp;#39;s hair.&lt;br /&gt;
5 - You&amp;#39;re never breaking any of your unit tests after each change.&lt;br /&gt;
4 - You&amp;#39;ve created macros in the IDE to help with almost all the steps.&lt;br /&gt;
3 - You&amp;#39;re refactoring your macros.&lt;br /&gt;
2 - Clippy is asking if you&amp;#39;ve heard about the &amp;quot;svn merge&amp;quot; command.&lt;br /&gt;
1 - TFS, on the other hand, still can&amp;#39;t offer you much help.&lt;br /&gt;
0 - Your Find/Replace drop-downs seem to read your mind.&lt;br /&gt;
&lt;/b&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=50065" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category></item><item><title>A Craftsman sometimes has to create his own tool</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/06/28/a-craftsman-sometimes-has-to-create-his-own-tool.aspx</link><pubDate>Sun, 28 Jun 2009 15:15:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:48803</guid><dc:creator>sergiopereira</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=48803</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/06/28/a-craftsman-sometimes-has-to-create-his-own-tool.aspx#comments</comments><description>&lt;p&gt;
	Today I was reading &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2009/06/28/fighting-fabricated-complexity.aspx" title="Fighting Fabricated Complexity - Patrick Smacchia [MVP C#] - CodeBetter.Com - Stuff you need to Code Better!"&gt;the latest one&lt;/a&gt; of the many excellent blog posts &lt;a href="http://codebetter.com/blogs/patricksmacchia/default.aspx" title="Patrick Smacchia [MVP C#] - CodeBetter.Com - Stuff you need to Code Better!"&gt;Patrick Smacchia&lt;/a&gt; has
	put out on the topic of code metrics and caring for your code&amp;#39;s quality. 
&lt;/p&gt;
&lt;p&gt;
	The passion this guy has for that topic is such that he has created &lt;b&gt;the&lt;/b&gt; best
	&lt;a href="http://www.ndepend.com/"&gt;tool for analyzing your code&lt;/a&gt;. But he doesn&amp;#39;t stop there. He wants to
	make sure we understand what is going on behind the seemingly magic CQL queries that
	ship with NDepend. He wants you to understand your code&amp;#39;s DNA; with the added bonus
	that you can actually improve that DNA.  
&lt;/p&gt;
&lt;p&gt;
	That&amp;#39;s Science with capital S. 
&lt;/p&gt;
&lt;ol&gt;	
	&lt;li&gt;First you understand the problem that you are trying 
	to fight (code complexity/unmaintainable software,) &lt;/li&gt;
	&lt;li&gt;you research ways to quantify it (the metrics,)&lt;/li&gt; 
	&lt;li&gt;you create some tool or device to extract that information from your subject,&lt;/li&gt;
	&lt;li&gt;you extract the metrics from a familiar subject,&lt;/li&gt;
	&lt;li&gt;you apply your knowledge of how #2 relates to #1 and improve the subject under analysis,&lt;/li&gt; 
	&lt;li&gt;you use the tool to verify the metrics have improved,&lt;/li&gt;
	&lt;li&gt;time shows you that the changes you made indeed reduced the problem at #1&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	I simply hate when someone criticizes Patrick&amp;#39;s posts as being just marketing material
	for his product. Let me tell you this. If I had that much dedication for software 
	quality, to the point that I had created a great product to empower everyone,
	I&amp;#39;d also be trying to explain the problem to you using the tool I wrote. Heck, I&amp;#39;m
	pretty sure if someone else had written NDepend Patrick would still be writing about
	these things and using the tool in the process.
&lt;/p&gt;
&lt;p&gt;
	I like code metrics and static analysis a lot as well, not nearly as much as Mr Smacchia though.
	I&amp;#39;m very excited that very soon I&amp;#39;ll get to use it in our code base, in our CI server.  I can&amp;#39;t
	wait to learn more about this science and inflict positive changes in our code. Like 
	everybody else, we know there&amp;#39;s dirt and bad smells in our code and it&amp;#39;s just awesome that
	there&amp;#39;s a tool that can help us clearly identify, mitigate, and track it.
&lt;/p&gt;
&lt;p&gt;
	My hope is that I&amp;#39;ll be able to come back here and share what I&amp;#39;ve learned about my
	code and how the process we went through to improve it.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=48803" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category></item><item><title>So you've been hearing about this Git thing</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/06/02/so-you-ve-been-hearing-about-this-git-thing.aspx</link><pubDate>Tue, 02 Jun 2009 17:11:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:47582</guid><dc:creator>sergiopereira</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=47582</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/06/02/so-you-ve-been-hearing-about-this-git-thing.aspx#comments</comments><description>&lt;p&gt;
  The ALT.NET universe in Chicago gets together again on &lt;a href="http://chicagoalt.net/event/June2009Meeting-GitWithoutPuns"&gt;June 10&lt;sup&gt;th&lt;/sup&gt;&lt;/a&gt;, this time to learn and talk about &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt;, the
  SCM you&amp;#39;re probably tired of hearing people jabbering about and still have not taken the time to look at.
&lt;/p&gt;
&lt;p&gt;
   The presenter will be myself and I hope to explain how Git works and how it can be a good alternative even for non open source projects.
&lt;/p&gt;

&lt;h3&gt;Git Without Puns&lt;/h3&gt;
	&lt;p&gt;
This month we will take a look at &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt;, a
distributed version control system that has been gaining a lot of
popularity since its introduction.
&lt;/p&gt;
&lt;p&gt;
As with everything that is new and is touted as a replacement for an existing
product, it&amp;#39;s easy to try and map Git&amp;#39;s functionality to 
&lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt;, &lt;a href="http://www.nongnu.org/cvs/"&gt;CVS&lt;/a&gt;

or &lt;a href="http://msdn.microsoft.com/en-us/library/ms181237%28VS.80%29.aspx"&gt;TFS&lt;/a&gt; for example.
To better use Git, we should avoid too much comparison and also try to understand how
it was built and how it works under the hood.
&lt;/p&gt;
&lt;p&gt;
Here are the things we will be seeing and discussing in this session.
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Brief tour of Git on Windows (SSH, PuTTY, Git Bash, GUI)&lt;/li&gt;
	&lt;li&gt;Git is distributed. How does that benefits me?&lt;/li&gt;
	&lt;li&gt;Git&amp;#39;s object database.&lt;/li&gt;

	&lt;li&gt;Git&amp;#39;s main objects (blobs, trees, commits and tags)&lt;/li&gt;
	&lt;li&gt;Git workflows. Choose or create yours.&lt;/li&gt;
	&lt;li&gt;
		Working with Git
		&lt;ul&gt;
			&lt;li&gt;Configuration tips&lt;/li&gt;
			&lt;li&gt;Create a repo&lt;/li&gt;

			&lt;li&gt;Clone a repo&lt;/li&gt;
			&lt;li&gt;Add/Commit changes&lt;/li&gt;
			&lt;li&gt;Reference another repo&lt;/li&gt;
			&lt;li&gt;Update repo (to/from)&lt;/li&gt;
			&lt;li&gt;Branching, merging, rebasing&lt;/li&gt;
		&lt;/ul&gt;

	&lt;/li&gt;
	&lt;li&gt;Hosting Git&lt;/li&gt;
	&lt;li&gt;Github, social project forking&lt;/li&gt;
  &lt;/ul&gt;

&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=47582" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/alt.net/default.aspx">alt.net</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Announcement/default.aspx">Announcement</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Community/default.aspx">Community</category></item><item><title>The Chicago Code Camp has got you covered</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/05/19/the-chicago-code-camp-has-got-you-covered.aspx</link><pubDate>Tue, 19 May 2009 07:09:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:46904</guid><dc:creator>sergiopereira</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=46904</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/05/19/the-chicago-code-camp-has-got-you-covered.aspx#comments</comments><description>&lt;p&gt;
As a brief inspection of your RSS reader will quickly tell you, it&amp;#39;s Code Camp season. Not to be
left out of this party, the developers in the Chicago and Milwaukee areas have a great option this year.
&lt;/p&gt;
&lt;p&gt;

The &lt;a href="http://chicagocodecamp.com/"&gt;Chicago Code Camp&lt;/a&gt;, which happens on May 30th, is 
&lt;a href="http://chicagocodecamp.com/Location.html"&gt;strategically located&lt;/a&gt; right between 
these two cities. 
&lt;/p&gt;
&lt;p&gt;

The &lt;a href="http://chicagocodecamp.com/Agenda.html"&gt;agenda has been published&lt;/a&gt; and it&amp;#39;s pretty exciting to see so many interesting
and useful topics in a single event.
&lt;/p&gt;
&lt;p&gt;
.NET still dominates the schedule but there&amp;#39;s a lot of options for developers of virtually all walks of
life. Here&amp;#39;s a quick summary (we will have 33 sessions but some cover more than one topic)
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;.NET:&lt;/b&gt;&lt;i&gt; 20 sessions&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ruby:&lt;/b&gt;&lt;i&gt; 6 sessions&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TDD:&lt;/b&gt;&lt;i&gt; 6 sessions&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JavaScript:&lt;/b&gt;&lt;i&gt; 3 sessions&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Functional Programming:&lt;/b&gt;&lt;i&gt; 3 sessions&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Cloud computing:&lt;/b&gt;&lt;i&gt; 3 sessions&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Python:&lt;/b&gt;&lt;i&gt; 2 sessions&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Java:&lt;/b&gt;&lt;i&gt; 2 sessions&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The bad part is that we can&amp;#39;t be at all the sessions we&amp;#39;d like &amp;mdash; there will be 5 or 6 concurrent talks. Here are some sessions that interest me in particular:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://chicagocodecamp.com/Sessions.html#Haml"&gt;Haml / Sass / Tenplate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://chicagocodecamp.com/Sessions.html#Firefox_Extensions"&gt;Firefox Extensions: Making Your Web Application More Accessible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://chicagocodecamp.com/Sessions.html#CodeContracts"&gt;Guarding your code with Code Contracts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://chicagocodecamp.com/Sessions.html#TDD_JavaScript"&gt;TDD and JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://chicagocodecamp.com/Sessions.html#Rail_AspNet"&gt;Rails-like development using ASP.NET&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://chicagocodecamp.com/Sessions.html#Ruby_Kata"&gt;Ruby Kata and Sparring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://chicagocodecamp.com/Sessions.html#Python"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://chicagocodecamp.com/Sessions.html#Gui_UnitTest"&gt;Limelight&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Those are only a few of the talks. I&amp;#39;m sure you&amp;#39;ll be able to find sessions of your own interest. 
RSVP below. Hope to see you there.
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://chicagocodecamp-Blogs.eventbrite.com"&gt;&lt;img alt="RSVP" src="http://www.eventbrite.com/static/images/button_ext/register_now_2.gif" border="0" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=46904" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Announcement/default.aspx">Announcement</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Community/default.aspx">Community</category></item><item><title>Git, SSH, PuTTY, GitHub, Unfuddle, the kitchen sink</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/05/06/git-ssh-putty-github-unfuddle-the-kitchen-sink.aspx</link><pubDate>Wed, 06 May 2009 09:09:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:46514</guid><dc:creator>sergiopereira</dc:creator><slash:comments>16</slash:comments><description>&lt;p&gt;
   After reading a good number of the guides for getting 
   &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt;/
   &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt;/
   &lt;a href="http://unfuddle.com"&gt;Unfuddle&lt;/a&gt; working correctly in Windows,
   I finally got it sorted out. I had to use a bunch of things I had not
   used before so I realized it&amp;#39;s probably a good idea to share my findings, hoping
   to help someone else (and maybe myself again) in the future.
&lt;/p&gt;

&lt;h3&gt;Local git is easier&lt;/h3&gt;
&lt;p&gt;
	Getting Git to run locally in Windows is not hard. It gets a little
	trickier when you want to work with remote repositories. Especially
	if, like me, you have little or no experience using SSH in Windows.
&lt;/p&gt;
&lt;p&gt;
	In this post I&amp;#39;ll install and configure the tools that enable Git
	to work with remote repositories (e.g. post changes to a server), which 
	I think is probably what a lot of people will want to do, even if you&amp;#39;re just 
	toying with Git or evaluating it.
&lt;/p&gt;

&lt;h3&gt;You will need SSH for serious Gitting&lt;/h3&gt;
&lt;p&gt;
	The way Git will authenticate and communicate with hosted repositories like GitHub or 
	Unfuddle is through an &lt;a href="http://en.wikipedia.org/wiki/Secure_Shell"&gt;SSH&lt;/a&gt;
	tunnel. That means we will need an SSH client to connect to the server
	and Git will use that connection to securely transfer the repository data
	up and down.
&lt;/p&gt;
&lt;p&gt;
	In Linux or on the Mac, SSH is a trivial thing. It&amp;#39;s just part of the default
	installation. For whatever reason, Windows does not come with an SSH client, so
	we need to find ourselves a 3rd party client.
&lt;/p&gt;


&lt;h3&gt;PuTTY, a family of tools&lt;/h3&gt;
&lt;p&gt;
	Luckily for us, there&amp;#39;s a free and very popular SSH client for Windows,	called
	&lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/"&gt;PuTTY&lt;/a&gt;. PuTTY is
	actually a family of utilities that play together to configure and establish
	SSH (and Telnet) connections.
&lt;/p&gt;
&lt;p&gt;
	From the PuTTY &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"&gt;downloads
	page&lt;/a&gt; get the following programs and put somewhere in your hard disk. I like to put these
	types of things in a c:\tools\bin directory, which is included in my &lt;code&gt;%PATH%&lt;/code&gt;.
&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe"&gt;putty.exe&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe"&gt;plink.exe&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://the.earth.li/~sgtatham/putty/latest/x86/pageant.exe"&gt;pageant.exe&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://the.earth.li/~sgtatham/putty/latest/x86/puttygen.exe"&gt;puttygen.exe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Create your SSH key pair&lt;/h3&gt;
&lt;p&gt;
	The most common way to authenticate your SSH connection with the server is
	using an &lt;a href="http://en.wikipedia.org/wiki/RSA"&gt;RSA&lt;/a&gt; key pair. The
	pair contains a public key and a private key. Typically these keys will be
	stored in two files &amp;mdash; make sure that the private key file is in a
	directory location that only your user account has rights. I&amp;#39;m gonna
	keep both files in &lt;code&gt;%USERPROFILE%\SSH&lt;/code&gt; (type &lt;code&gt;echo %USERPROFILE%&lt;/code&gt;
	in a command window to see where yours is.)
&lt;/p&gt;
&lt;p&gt;
	To create a key pair we will use &lt;i&gt;puttygen.exe&lt;/i&gt;. Just click &lt;i&gt;Generate&lt;/i&gt; and then
	&lt;i&gt;Save public key&lt;/i&gt; and &lt;i&gt;Save private key&lt;/i&gt;. I chose to leave the password blank
	and trust that my directory security is enough to protect my keys. Let&amp;#39;s assume I saved 
	my keys at &lt;code&gt;%USERPROFILE%\SSH\private.ppk&lt;/code&gt; and &lt;code&gt;%USERPROFILE%\SSH\public.ppk&lt;/code&gt;, 
	respectively.
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/puttygen.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/puttygen_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;We&amp;#39;re not done with PuTTY yet&lt;/h3&gt;
&lt;p&gt;
	Before starting an SSH connection with PuTTY, we need to run Pageant.exe. Pageant is a
	background process that will handle the authentication requests. We will add our private key(s)
	in Pageant and it will keep them available for new connections, without the need to
	retype the password (if you entered one) every single time.
&lt;/p&gt;
&lt;p&gt;
	Run Pageant.exe, double click its icon in the notification area, and add your private key file.
	If you specified a password, it will now prompt you for that.
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/pageant_2D00_1.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/pageant_2D00_1_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	Phew! We are done with the SSH crap. Now on to Git. Finally.
&lt;/p&gt;

&lt;h3&gt;Git via msysgit&lt;/h3&gt;
&lt;p&gt;
	There are a few ways of installing the git client in Windows, including downloading
	and compiling the source. But guess if I want to go down that route. Instead,
	let&amp;#39;s just press the easy button and use a pre-packaged installer.
&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt; is what you&amp;#39;ll want to
	install. Donwload the latest release from the site. The file name of the full installer, 
	as of this writing,	will be named like &lt;i&gt;Git-&lt;b&gt;[version]&lt;/b&gt;-preview&lt;b&gt;[yyyymmdd]&lt;/b&gt;.exe&lt;/i&gt;.
&lt;/p&gt;
&lt;p&gt;
	Run the installer accepting most of the defaults, with the exception of these
	two screens below. We want to &lt;b&gt;Run Git from the Windows Command Prompt&lt;/b&gt;
	and &lt;b&gt;Use PLink&lt;/b&gt; (PuTTY.)
&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/msysgit.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/msysgit_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;
	&amp;nbsp;
	&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/msysgit_2D00_2.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/msysgit_2D00_2_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
	After this we should have a working installation of Git. You should be
	able to use Git from both the Windows command prompt and from the Git Bash
	shell.
&lt;/p&gt;

&lt;h3&gt;Register your public key with the remote server&lt;/h3&gt;
&lt;p&gt;
	Now we need to tell the server that hosts the remote repository that
	it should expect and accept SSH connections from our machine. The
	way we do this is similar in GitHub and Unfuddle. We just need to 
	associate our &lt;b&gt;public&lt;/b&gt; key with our account on that site.
&lt;/p&gt;
&lt;p&gt;
	For example, in my GitHub account settings there&amp;#39;s a section 
	called &lt;i&gt;SSH Public Keys&lt;/i&gt;, where we can add all public keys that we own. Don&amp;#39;t use 
	the public key straight from your PuTTY public key file, it uses a different format.
	Instead, open Puttygen again and load the &lt;b&gt;private&lt;/b&gt; key. The public key,
	in the right format, will be shown in the big text box at the top of the window. Copy
	that entire text and paste in a new key in your GitHub settings, as seen below.
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/github_2D00_ssh.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2009.05/github_2D00_ssh_2D00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Troubleshooting&lt;/h3&gt;
&lt;p&gt;
	After all that you should have all it takes to use Git in Windows. Until I
	got to this point I came across some problems. Here are some of them.
&lt;/p&gt;
&lt;p&gt;
	&lt;b&gt;No supported authentication methods available&lt;/b&gt;. I got that error while trying
	to &lt;i&gt;push&lt;/i&gt; changes because I either forgot to run Pageant or to add the right
	key into it. The full error is below.
&lt;/p&gt;
&lt;pre&gt;C:\myproject&amp;gt;git push origin master
FATAL ERROR: Disconnected: No supported authentication methods available
fatal: The remote end hung up unexpectedly&lt;/pre&gt;
&lt;p&gt;
	&lt;b&gt;The server&amp;#39;s host key is not cached in the registry&lt;/b&gt;. Sometimes when
	connecting to a remote server for the first time, the PuTYY will output this
	message after your Git command.
&lt;/p&gt;
&lt;pre&gt;The server&amp;#39;s host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server&amp;#39;s rsa2 key fingerprint is:
ssh-rsa 1024 [fingerprint here]
If you trust this host, enter &amp;quot;y&amp;quot; to add the key to
PuTTY&amp;#39;s cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter &amp;quot;n&amp;quot;.
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n)&lt;/pre&gt;
&lt;/p&gt;
	The problem is that Git will not read your keyboard input so
	you can&amp;#39;t type &amp;quot;y&amp;quot; (or &amp;quot;n&amp;quot;). You have to CTRL+C out of it.
&lt;/p&gt;
&lt;p&gt;
	The fix for this, is to connect to your server initially using
	&lt;code&gt;plink -agent github.com&lt;/code&gt; directly and then you&amp;#39;ll be able to press &amp;quot;y&amp;quot; to cache
	the server&amp;#39;s key locally (and not be prompted again in Git.) Enter &amp;quot;git&amp;quot; as the username if
	prompted. Now we can get back to Git without that prompt.
&lt;/p&gt;

&lt;h3&gt;Now, that was nerdy&lt;/h3&gt;
&lt;p&gt;
	By now, if you got this far in this post, you&amp;#39;re probably thinking this is too much work
	just to get a simple Git client working. I think the current situation reflects at least two
	things: the people behind Git are definitely not Windows users (d&amp;#39;oh, what a surprise) and
	the toolset is still relatively immature (in terms of polish, not under the hood) compared
	to Subversion and CVS for example. The existing GUI&amp;#39;s are still very raw and young but, given
	the increasing popularity of Git, I&amp;#39;ll be surprised if by the end of this year this problem
	isn&amp;#39;t gone.
&lt;/p&gt;

&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=46514" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category></item><item><title>Taking PeepCode for a spin</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/04/28/taking-peepcode-for-a-spin.aspx</link><pubDate>Tue, 28 Apr 2009 08:25:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:46283</guid><dc:creator>sergiopereira</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=46283</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/04/28/taking-peepcode-for-a-spin.aspx#comments</comments><description>&lt;p&gt;
   A rainy weekend and some brain hunger made me finally do something I had been meaning to do for a while. 
   Once I &lt;a href="http://devlicio.us/blogs/sergio_pereira/archive/2008/07/20/the-new-crop-of-net-screencasts.aspx"&gt;posted about my interest in screencasts&lt;/a&gt; 
   and their power to make information memorable. This last weekend I filled up my shopping cart over at
   &lt;a href="http://www.peepcode.com"&gt;PeepCode&lt;/a&gt; with a bunch of material that was on my &lt;i&gt;to watch&lt;/i&gt;
   list. 
&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://peepcode.com/products/git"&gt;GIT&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;
	This video was pretty interesting. It will definitely let you get off the ground quickly
	with &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt;. I learned and still remember more from
	this screencast than from any other time spent on documentation and tutorials.
&lt;/p&gt;
&lt;p&gt;
	This is one of those screencasts where the author starts cranking out commands 
	at the command line. If you can&amp;#39;t stand the command line, you won&amp;#39;t like this one.
	The advantage is that the command line is the same in all platforms.
&lt;/p&gt;
&lt;p&gt;
	My only negative comments, which is applicable to almost all the other videos I&amp;#39;ve 
	watched, is that the author has the habit of clearing the screen way too early
	and often. At least it&amp;#39;s recorded so you can rewind and absorb the information
	at your own pace.
&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://peepcode.com/products/git-internals-pdf"&gt;GIT Internals (PDF)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;
	While on my git learning mode, I went ahead and bought this PDF as well. Boy, this is
	money. If you&amp;#39;re a sucker for internal details, this one is for you.
&lt;/p&gt;
&lt;p&gt;
	The PDF was written by &lt;a href="http://jointheconversation.org/"&gt;Scott Chacon&lt;/a&gt;,
	who is very well known in git circles. The material is dense but is very well
	explained by Scott. Worth every penny.
&lt;/p&gt;
&lt;p&gt;
	The PDF ships with some videos from &lt;a href="http://www.gitcasts.com/"&gt;gitcasts&lt;/a&gt; and
	some handy shell shortcuts.
&lt;/p&gt;

&lt;h3&gt;Rails from Scratch &lt;a href="http://peepcode.com/products/rails-from-scratch-part-i"&gt;Part 1&lt;/a&gt; and &lt;a href="http://peepcode.com/products/rails-from-scratch-part-ii"&gt;Part 2&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;
	I already have a reasonable level of experience with Rails. What made me buy these two episodes
	was to see a competent Rails programmer showing how he works. After watching both videos I was happy to
	see that I was not so far off. I know these screencasts are definitely simplified for the newbie and
	that a number of things changed in Rails since the first edition of this material, but
	the good advices on how to organize code and use the Rake tasks are still valid.
&lt;/p&gt;
&lt;p&gt;
	There&amp;#39;s a whole lot more to Rails than it&amp;#39;s possible to cram in 2h40 of screencasts but 
	if you need to start somewhere, this is a good choice. I wish there was a little more
	ActiveRecord and plugins covered but, hey, it&amp;#39;s still one of the greatest bargains out there.
&lt;/p&gt;


&lt;h3&gt;&lt;a href="http://peepcode.com/products/objective-c-for-rubyists"&gt;Objective-C for Rubyists&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;
	I just started watching this one. My early impression (25 minutes in) is that its pace
	is a little too frantic. I don&amp;#39;t buy the argument that knowing Ruby helps you learning
	Objective-C because of their SmallTalk heritage.
&lt;/p&gt;
&lt;p&gt;
	I&amp;#39;ve been trying to get into Objective-C from books and whitepapers but I had hopes a
	screencast like this would be more effective. I&amp;#39;m not too optimistic so far (I&amp;#39;ll update
	this post if I&amp;#39;m convinced otherwise.)
&lt;/p&gt;

&lt;h3&gt;Worth the investment&lt;/h3&gt;
&lt;p&gt;
	A good thing with the PeepCode episodes is that they are positioned at a price point (US $9.00) that
	doesn&amp;#39;t let you feel too bad, even if you expected more of them. They have definitely been worth more 
	than the sticker price.
&lt;/p&gt;
&lt;p&gt;
	I&amp;#39;m looking forward to a few more episodes later this year. RSpec and Haml are on my crosshair.
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=46283" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/review/default.aspx">review</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Video/default.aspx">Video</category></item><item><title>Blocked .js files keep biting me</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/04/03/blocked-js-files-keep-biting-me.aspx</link><pubDate>Sat, 04 Apr 2009 03:14:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:45379</guid><dc:creator>sergiopereira</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=45379</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/04/03/blocked-js-files-keep-biting-me.aspx#comments</comments><description>&lt;p&gt;
This is a tip for those working with JavaScript (and possibly other types of files) that is freely available for download. For the n&lt;sup&gt;th&lt;/sup&gt; time in the last few months I spent an unnecessary amount of time trying to find a problem in my code that wasn&amp;#39;t really there.
&lt;/p&gt;
&lt;p&gt;
Windows keeps track of the files you save to your hard disk which came from the Internet. Maybe you have seen this problem when you try to open a CHM file that you downloaded and see that it opens to a blank page. The same type of thing happens with JavaScript files that you download. Let&amp;#39;s see what happened to me today.
&lt;/p&gt;
&lt;p&gt;First I downloaded the latest version of &lt;a href="http://docs.jquery.com/QUnit"&gt;QUnit&lt;/a&gt; and saved to my application&amp;#39;s directory. I did this the usual way, as shown in the image below.
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/save_5F00_js.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/save_5F00_js_5F00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Then I proceeded to use the downloaded testrunner.js file in my HTML page, via a &lt;code&gt;&amp;lt;script src=&amp;quot;testrunner.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; tag. When I tried to open my HTML page, I was not expecting to see the particular error shown below.
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/error_5F00_js.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/error_5F00_js_5F00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;I started to look for common problems: Did I save the file in the right place? Did I spell its name right? Did I mispell the function name? Did I miss a dependency? No, no, no, and no. All looked good.
&lt;/p&gt;

&lt;p&gt;That&amp;#39;s when I remembered that the file might have been flagged by Windows. I opened its properties dialog and, sure enough, there it was, the infuriating &lt;i&gt;Unblock&lt;/i&gt; button. 
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/properties_5F00_js.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/properties_5F00_js_5F00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ah, that&amp;#39;s easy. I just clicked it and refreshed my page. Wah-wah! Problem persists. I tried typing the .js url in the address bar and saw this 401 error message from IIS, not 404. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/err_5F00_403.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/err_5F00_403_5F00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;That told me that there was still something messed up with file access. I checked the file&amp;#39;s permissions, comparing to an older .js file in the application. The new one did not grant access to local users, so I added Read access to local users.
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/security_5F00_js.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/security_5F00_js_5F00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;
Now it works. Depending on how your IIS and/or ASP.NET security is configured, you may not need this last step (e.g. if the process identity already has admin rights, in which case I salute you, brave friend.) The system at hand was a Win2008-x64 installation with the default IIS/ASP.NET settings.
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/fixed_5F00_js.png"&gt;&lt;img src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sergio_5F00_pereira.2008.04/fixed_5F00_js_5F00_small.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;
	This problem seems to happen to me every other week and I still did
	not develop the reflex to take care of it right when I download the file. 
	On the other hand, I&amp;#39;m getting better at remembering about it when I
	see stuff like &lt;i&gt;&amp;quot;function not defined&amp;quot;&lt;/i&gt; in an error message. 
	
&lt;/p&gt; &lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=45379" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tips-and-Tricks/default.aspx">Tips-and-Tricks</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/JavaScript/default.aspx">JavaScript</category></item><item><title>Easy project administration with Unfuddle</title><link>http://devlicious.com/blogs/sergio_pereira/archive/2009/03/08/easy-project-administration-with-unfuddle.aspx</link><pubDate>Sun, 08 Mar 2009 08:12:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44861</guid><dc:creator>sergiopereira</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicious.com/blogs/sergio_pereira/rsscomments.aspx?PostID=44861</wfw:commentRss><comments>http://devlicious.com/blogs/sergio_pereira/archive/2009/03/08/easy-project-administration-with-unfuddle.aspx#comments</comments><description>&lt;p&gt;
	I don&amp;#39;t come out often to sing praises for any product, I&amp;#39;d
	say I even tend to complain more than anything. That said, sometimes
	I come across a product that strikes all the right chords. 
&lt;/p&gt;

&lt;p&gt;
	Recently I started using &lt;a href="http://unfuddle.com"&gt;Unfuddle&lt;/a&gt; and
	...just Wow! What a delightful experience. I can&amp;#39;t say I was exactly
	surprised because I had heard really good things about it from a few
	people. Still, it&amp;#39;s great to try it and confirm that same impression. 
&lt;/p&gt;
&lt;p&gt;
    Unfuddle is clearly  a product that was built with a lot of love and
    by people that &lt;a href="http://blog.adsdevshop.com/2009/02/06/unfuddle-their-story/"&gt;understand
    the problem that needs to be solved&lt;/a&gt;. 
&lt;/p&gt;
&lt;h3&gt;Migrating a project - the Repository&lt;/h3&gt;
&lt;p&gt;
	I started moving one of my projects to Unfuddle. I started creating a new
	project and, with help from their support team, I moved my SVN repository
	(with the complete log history) into the project&amp;#39;s repository.
&lt;/p&gt;
&lt;p&gt;
	The repository browser offers all you&amp;#39;d expect from a 1st class product.
	You can easily navigate the repository tree and go back an forth in the
	revisions trail. You can see what was changed in each commit, see the
	file by file diffs, and post notifications whenever a commit happens (great
	way to trigger your CI process.) 
&lt;/p&gt;

&lt;h3&gt;Managing the project&lt;/h3&gt;
&lt;p&gt;
	Right now I&amp;#39;m in the process of moving the list of bugs and
	planned features into the ticketing system. In Unfuddle
	I can plan milestones and version numbers for my project 
	and associated tickets to them, which will let me see
	how far the project is from each milestone right in the
	project&amp;#39;s dashboard.
&lt;/p&gt;
&lt;p&gt;
	Unfuddle reminds me of &lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt;,
	with the important difference that I don&amp;#39;t need to go through the
	pain of getting it up an running and that configuring your project
	(or as many projects as you want) is much simpler.
&lt;/p&gt;
&lt;p&gt;
	One important thing for me in any product like this is the 
	ability to create and maintain documents. This is provided through
	the Notebooks feature, which allows us to create collections of pages
	with basic formatting. If you need something much richer, like
	a diagram, or include an existing Word document, you can attach
	files to a notebook. A real file repository is probably a feature
	that could make Unfuddle even better.
&lt;/p&gt;

&lt;h3&gt;Other nice things&lt;/h3&gt;
&lt;p&gt;
	I love how Unfuddle allows us to use 
	&lt;a href="http://daringfireball.net/projects/markdown/syntax"&gt;Markdown&lt;/a&gt; 
	or &lt;a href="http://hobix.com/textile/"&gt;Textile&lt;/a&gt; to format pretty much
	everything that is important, like ticket descriptions and notebook text.
&lt;/p&gt;
&lt;p&gt;
	Unfuddle also supports git. I haven&amp;#39;t been using git yet, but it&amp;#39;s good
	to know that I&amp;#39;ll probably not need to go looking for another service
	if I choose to migrate to git.
&lt;/p&gt;


&lt;h3&gt;Very important disclaimer&lt;/h3&gt;
&lt;p&gt;
	Although I could probably get by with just the free plan in Unfuddle,
	I received a complimentary subscription to their Compact plan. The
	only important differences for my use cases would be the number of
	notebook pages and the ability to attach files.
&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicious.com/aggbug.aspx?PostID=44861" width="1" height="1"&gt;</description><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/Development/default.aspx">Development</category><category domain="http://devlicious.com/blogs/sergio_pereira/archive/tags/review/default.aspx">review</category></item></channel></rss>