<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>David Laing's blog</title>
	
	<link>http://davidlaing.com</link>
	<description>Craftmanship over crap</description>
	<lastBuildDate>Mon, 22 Feb 2010 12:18:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9-rare</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/DavidLaing" /><feedburner:info uri="davidlaing" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>HOWTO Reset MySQL 5.0 root password in Ubuntu 8.04 LTS</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/javP6VHLGtE/</link>
		<comments>http://davidlaing.com/2009/09/19/howto-reset-mysql-5-0-root-password-in-ubuntu-8-04-lts/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 15:20:08 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[HOWTO]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=194</guid>
		<description><![CDATA[Turns out there are lots of complicated ways, but in Ubuntu you can just reconfigure the package:

dpkg-reconfigure mysql-server-5.0

Hopefully that will save someone some hair pulling
]]></description>
			<content:encoded><![CDATA[<p>Turns out there are lots of complicated ways, but in Ubuntu you can just reconfigure the package:</p>
<p><code><br />
dpkg-reconfigure mysql-server-5.0<br />
</code></p>
<p>Hopefully that will save someone some hair pulling</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2009/09/19/howto-reset-mysql-5-0-root-password-in-ubuntu-8-04-lts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2009/09/19/howto-reset-mysql-5-0-root-password-in-ubuntu-8-04-lts/</feedburner:origLink></item>
		<item>
		<title>Utils anti-pattern &amp; AutoMapper</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/gXrCeBOfnqo/</link>
		<comments>http://davidlaing.com/2009/06/02/utils-anti-pattern-automapper/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 09:18:41 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Code smells]]></category>
		<category><![CDATA[automapper]]></category>
		<category><![CDATA[utils-anti-pattern]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=190</guid>
		<description><![CDATA[These are more for my reference purposes &#8211; hopefully you&#8217;ll find them useful:
If you&#8217;re about to name a class **Util; think harder &#8211; there is a better name that discribes what that class is for:
Chriss Missal has some advice for you
Faced with the prospect of heaps of left hand side => right hand side code [...]]]></description>
			<content:encoded><![CDATA[<p>These are more for my reference purposes &#8211; hopefully you&#8217;ll find them useful:</p>
<p>If you&#8217;re about to name a class **Util; think harder &#8211; there is a better name that discribes what that class is for:<br />
<a href="http://www.lostechies.com/blogs/chrismissal/archive/2009/06/01/anti-patterns-and-worst-practices-utils-class.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.lostechies.com/blogs/chrismissal/archive/2009/06/01/anti-patterns-and-worst-practices-utils-class.aspx');">Chriss Missal has some advice for you</a></p>
<p>Faced with the prospect of heaps of left hand side => right hand side code in your DTO of anti-corruption layer?  Consider <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx');">Jimmy Bogard&#8217;s Automapper</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2009/06/02/utils-anti-pattern-automapper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2009/06/02/utils-anti-pattern-automapper/</feedburner:origLink></item>
		<item>
		<title>The Pomodoro Technique – Scrum in the small</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/0vwRRV7kRGA/</link>
		<comments>http://davidlaing.com/2009/05/31/the-pomodoro-technique-scrum-in-the-small/#comments</comments>
		<pubDate>Sun, 31 May 2009 09:57:41 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[HOWTO]]></category>
		<category><![CDATA[Software Craftmanship]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=182</guid>
		<description><![CDATA[Over the past month I&#8217;ve been experimenting with the pomodoro technique of time management to great success.
The technique is surprisingly simple; yet I&#8217;ve found it contains a wealth of physical and emotional benefits.  To give some context; I&#8217;m using it as a programmer as part of a agile scrum team.  I typically program [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past month I&#8217;ve been experimenting with the pomodoro technique of time management to great success.</p>
<p>The technique is surprisingly simple; yet I&#8217;ve found it contains a wealth of physical and emotional benefits.  To give some context; I&#8217;m using it as a programmer as part of a agile scrum team.  I typically program using TDD techniques.  That being said,  I don&#8217;t see why it wouldn&#8217;t be applicable in most &#8220;desk&#8221; based jobs.</p>
<p>A pomodoro is a unit of focused, uninterrupted time; measured by an egg timer.  For me, 25 minutes works well.</p>
<p>At the beginning of my work day, I write a collection of tasks that I think I achieve in the day onto a fresh piece of paper as my todo list.  I estimate how long I think each task will take in units of a pomodoros. Next to each task I put a number of boxes; one for each pomodoro unit.  I make sure not to have more pomodoro units than I achieved yesterday; and I try to make sure that I&#8217;m estimating tasks based on how long similar tasks actually took me in the past.</p>
<p>Then I wind up my egg timer, place it visibly on my desk and begin the first task.  The ritual of winding up the timer, placing it down and hearing it tick help me to drop into the zone of full concentration &#8211; and let my team know that they shouldn&#8217;t interrupt me.</p>
<p><em>Brrrriiinng</em>.  Pomodoro up, finish the current test and stop.  Cross out one of the boxes on my todo list.  Get up and leave my desk; stretch, drink some water, focus on something far away to relax the eyes, go an speak to anyone who came past during my pomodoro time &#038; was waived away.</p>
<p>Then back to the desk, reassess which is now the most important task to get one with, and start the next Pomodoro.</p>
<p>At the end of the day I transcribe the results of my todo list back to a records sheet; update our project management software (VersionOne); and leave, satisfied that I achieved what I set out to do.</p>
<p>I&#8217;ve found that running my day like this greatly increases my job satisfaction &#038; efficiency.</p>
<p>Firstly; I&#8217;m breaking my addition to hopium, and setting myself up to fail every day.  I used to live in this lala land called &#8211; I have 8 hours of productive work time each day.  The empirical reality shows that I usually do 5 &#8211; 8 pomodoro units / day &#8211; so much more like 3 &#8211; 4 hours.  The rest gets gobbled up by meetings, emails, conversations.  So its no wonder that I used to achieved half what I thought I would each day; and left work feeling disappointed.</p>
<p>Secondly, having a forced reset every 25 mins really helps me to stop falling down rabbit holes.  I&#8217;ll often be trying to solve a problem with a specific technique that just isn&#8217;t working, and if I&#8217;m not careful I can spend a whole afternoon bashing my head against a wall.  With the forced breaks, I&#8217;ll often find that I sit back down to the problem, and have a flash of inspiration for a much simpler way to solve it, or realise that I don&#8217;t even need to solve it in the first place!</p>
<p>Thirdly, being reminded to get away from my desk frequently really helps physically.  I&#8217;ve experienced much less &#8220;mouse shoulder&#8221; and dry eyes.</p>
<p>The technique is also really helpful when pairing; keeping meetings from rambling; keeping focussed on one task (rather than having to check email or twitter every 10 seconds) and getting going on a large daunting task.</p>
<p>If you struggle with hopium like me; I&#8217;d really encourage you to give the Pomodori technique a try for 2 weeks, and let me know how you get on in the comments to this post.</p>
<p><em>Brrriiinng</em> <img src='http://davidlaing.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Resources</strong><br />
<a href="http://www.pomodorotechnique.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.pomodorotechnique.com/');">www.pomodorotechnique.com</a><br />

<a href='http://davidlaing.com/2009/05/31/the-pomodoro-technique-scrum-in-the-small/pomodoro_records/' title='3 pomodoro_records'><img width="150" height="150" src="http://davidlaing.com/wp-content/2009/05/pomodoro_records-150x150.png" class="attachment-thumbnail" alt="Pomodoro - Records sheet" title="3 pomodoro_records" /></a>
<a href='http://davidlaing.com/2009/05/31/the-pomodoro-technique-scrum-in-the-small/pomodoro_todo_inventory/' title='1 pomodoro_todo_inventory'><img width="150" height="150" src="http://davidlaing.com/wp-content/2009/05/pomodoro_todo_inventory-150x150.png" class="attachment-thumbnail" alt="Pomodoro - Todo inventory sheet" title="1 pomodoro_todo_inventory" /></a>
<a href='http://davidlaing.com/2009/05/31/the-pomodoro-technique-scrum-in-the-small/pomodoro_todo_today/' title='2 pomodoro_todo_today'><img width="150" height="150" src="http://davidlaing.com/wp-content/2009/05/pomodoro_todo_today-150x150.png" class="attachment-thumbnail" alt="Pomodoro - Todo today sheet" title="2 pomodoro_todo_today" /></a>
</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2009/05/31/the-pomodoro-technique-scrum-in-the-small/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2009/05/31/the-pomodoro-technique-scrum-in-the-small/</feedburner:origLink></item>
		<item>
		<title>Howto uninstall a broken MSI</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/-bdFueaCNa0/</link>
		<comments>http://davidlaing.com/2009/05/27/howto-uninstall-a-broken-msi/#comments</comments>
		<pubDate>Wed, 27 May 2009 10:26:05 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[HOWTO]]></category>
		<category><![CDATA[msi]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=179</guid>
		<description><![CDATA[I&#8217;m busy creating an MSI installer package at work; and managed to get my system into a bit of a knot.
Basically, my custom action crashes on uninstall &#8211; so when I try to remove the broken MSI, it throws an error and rolls back the uninstall process.
AAARGH!  How do I remove the broken MSI [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m busy creating an MSI installer package at work; and managed to get my system into a bit of a knot.</p>
<p>Basically, my custom action crashes on uninstall &#8211; so when I try to remove the broken MSI, it throws an error and rolls back the uninstall process.</p>
<p>AAARGH!  How do I remove the broken MSI now that I&#8217;ve fixed the bug?</p>
<p>Fortunately MSKB supplies this helpful little tool:</p>
<p><a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;290301" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://support.microsoft.com/default.aspx?scid=kb;en-us;290301');">Windows Installer CleanUp Utility</a></p>
<p>Simply run, select offending MSI, and it will forceably remove any MSI registration from your system.  </p>
<p>Got me out of a pickle; and will hopefully do the same for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2009/05/27/howto-uninstall-a-broken-msi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2009/05/27/howto-uninstall-a-broken-msi/</feedburner:origLink></item>
		<item>
		<title>Symbolic links for WinXP</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/x00JGR9xCfY/</link>
		<comments>http://davidlaing.com/2009/03/11/symbolic-links-for-winxp/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 16:15:41 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[HOWTO]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=173</guid>
		<description><![CDATA[Hurrah &#8211; symbolic links have arrived for WinXP; via Junction.

  C:>junction.exe c:Test c:WINDOWS

Thanks for this great tip Nick
]]></description>
			<content:encoded><![CDATA[<p>Hurrah &#8211; symbolic links have arrived for WinXP; via Junction.</p>
<pre>
  C:>junction.exe c:Test c:WINDOWS
</pre>
<p>Thanks for <a href="http://www.sertis.net/tool-tip-junction-for-windows-xp" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.sertis.net/tool-tip-junction-for-windows-xp');">this great tip Nick</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2009/03/11/symbolic-links-for-winxp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2009/03/11/symbolic-links-for-winxp/</feedburner:origLink></item>
		<item>
		<title>Try/Catch for SQL!?</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/oSDkGn8Bf8Q/</link>
		<comments>http://davidlaing.com/2009/03/05/trycatch-for-sql/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 11:42:05 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[HOWTO]]></category>
		<category><![CDATA[MSSQL]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=167</guid>
		<description><![CDATA[Thanks to Nick Sertis for this trick &#8211; who knew TSQL could do try/catch statements!
Very useful when you need to write data manipulation scripts for production databases.

[-]?View Code SQL1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BEGIN TRY
&#160;
    BEGIN TRAN
&#160;
        --Some SQL
&#160;
&#160;
    COMMIT TRAN
&#160;
END TRY
-- Catch the errors on the [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to <a href="http://www.sertis.net" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.sertis.net');">Nick Sertis</a> for this trick &#8211; who knew TSQL could do try/catch statements!</p>
<p>Very useful when you need to write data manipulation scripts for production databases.</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p1672');">[<span id="p1672_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p167code2'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p1672"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p167code2"><pre class="sql">BEGIN TRY
&nbsp;
    BEGIN TRAN
&nbsp;
        <span style="color: #808080; font-style: italic;">--Some SQL</span>
&nbsp;
&nbsp;
    COMMIT TRAN
&nbsp;
END TRY
<span style="color: #808080; font-style: italic;">-- Catch the errors on the inserts</span>
BEGIN CATCH
&nbsp;
    ROLLBACK TRAN
    <span style="color: #993333; font-weight: bold;">SELECT</span> ERROR_MESSAGE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
END CATCH</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2009/03/05/trycatch-for-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2009/03/05/trycatch-for-sql/</feedburner:origLink></item>
		<item>
		<title>For a software craftsman, reducing technical debt should be as much of a habit as typing</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/JoyAMtFchcA/</link>
		<comments>http://davidlaing.com/2009/03/02/for-a-software-craftsman-reducing-technical-debt-should-be-as-much-of-a-habit-as-typing/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 08:40:05 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[Software Craftmanship]]></category>
		<category><![CDATA[Technical Debt]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=160</guid>
		<description><![CDATA[I was involved in an interesting group discussion with fellow craftsmen yesterday on Technical Debt at the 2009 Software Craftsmanship conference.
The question put to the group was:  &#8220;How should a team make time to reduce technical debt?&#8221;
I was interested that there was a totally unanamious response &#8211; &#8220;You shouldn&#8217;t&#8221;.  &#8220;You should be doing [...]]]></description>
			<content:encoded><![CDATA[<p>I was involved in an interesting group discussion with fellow craftsmen yesterday on Technical Debt at the <a href="http://www.softwarecraftsmanship.org.uk" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.softwarecraftsmanship.org.uk');">2009 Software Craftsmanship conference</a>.</p>
<p>The question put to the group was:  &#8220;How should a team make time to reduce technical debt?&#8221;</p>
<p>I was interested that there was a totally unanamious response &#8211; &#8220;You shouldn&#8217;t&#8221;.  &#8220;You should be doing tiny pieces of technical debt reduction <strong>all</strong> the time&#8221;.</p>
<p>Previously I have advocated creating <a href="/2008/06/30/when-to-make-technical-stories/">technical debt reduction stories</a>, and trying to schedule those into the iteration plan.  People thought this was in principal the wrong strategy; and indeed in my experience this approach doesn&#8217;t work.</p>
<p>The group felt that in general tackling technical debt reduction though large scale refactorings was the wrong approach &#8211; rather a craftsman should be making incremental improvements every time they touch the code.  </p>
<p><a href="http://www.informit.com/articles/article.aspx?p=1235624&#038;seqNum=6" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.informit.com/articles/article.aspx?p=1235624&#038;seqNum=6');">Bob Martin&#8217;s Boy Scout Rule:</a> &#8211; <em>check in your code a little cleaner than what you checked out</em> &#8211; encapsulates this principal.  Its the little refactorings that you make &#8211; removing a tiny piece of duplication, changing a variable name to better reveal intent; extracting an expression into a intention revealing method &#8211; that, over time, result in a clean, maintainable code base.</p>
<p>In a way, this is similar to implementing the &#8220;<a href="http://en.wikipedia.org/wiki/Fixing_Broken_Windows" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Fixing_Broken_Windows');">Fixing Broken Windows Theory</a>&#8221; in software development.  The theory is that having a zero tolerance attitude towards the little things makes a huge impact on the so called &#8220;bigger&#8221; things.  </p>
<p>Its perhaps easier understood if you consider what happens if you don&#8217;t care about the little things.  Its about the attitude &#8211; if I couldn&#8217;t care enough to clean up a messy bit of code; will my team mates care about a few broken tests?  If its okay to have a few broken tests; then it&#8217;s probably okay to ignore some bugs.  If its okay to ignore bugs; then who really needs to care about well defined acceptance tests?  And if the team doesn&#8217;t care about precise acceptance tests; why should the business care about unambiguous requirements.  You get the picture.</p>
<p>Its the little things, added up, that result in technical debt reduction.  </p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2009/03/02/for-a-software-craftsman-reducing-technical-debt-should-be-as-much-of-a-habit-as-typing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2009/03/02/for-a-software-craftsman-reducing-technical-debt-should-be-as-much-of-a-habit-as-typing/</feedburner:origLink></item>
		<item>
		<title>Functions with side effects are just rude!</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/3Pm_t-5c-b0/</link>
		<comments>http://davidlaing.com/2009/02/25/functions-with-side-effects-are-just-rude/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 14:30:26 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Code smells]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=155</guid>
		<description><![CDATA[Today I fell into a trap when using a function that had a side effect &#8211; it unexpectedly changed an input parameter; causing a later statement to fail.  Debugging took an age!
For example, consider the following function:

[-]?View Code CSHARP1
      string StringReplace&#40;string haystack, string needle&#41;

If this function is side-effect free, [...]]]></description>
			<content:encoded><![CDATA[<p>Today I fell into a trap when using a function that had a side effect &#8211; it unexpectedly changed an input parameter; causing a later statement to fail.  Debugging took an age!</p>
<p>For example, consider the following function:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p1555');">[<span id="p1555_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p155code5'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p1555"><td width="1%" class="line_numbers"><pre>1
</pre></td><td class="code" id="p155code5"><pre class="csharp">      <span style="color: #FF0000;">string</span> StringReplace<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span> haystack, <span style="color: #FF0000;">string</span> needle<span style="color: #000000;">&#41;</span></pre></td></tr></table></div>

<p>If this function is side-effect free, we can use it without fear like this:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p1556');">[<span id="p1556_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p155code6'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p1556"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p155code6"><pre class="csharp">        <span style="color: #FF0000;">string</span> menagerie <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;cat,dog,bee,llama&quot;</span><span style="color: #008000;">;</span>
        <span style="color: #FF0000;">string</span> catFreeMenagerie <span style="color: #008000;">=</span> StringReplace<span style="color: #000000;">&#40;</span>menagerie, <span style="color: #666666;">&quot;cat&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #FF0000;">string</span> beeFreeMengerie <span style="color: #008000;">=</span> StringReplace<span style="color: #000000;">&#40;</span>menagerie, <span style="color: #666666;">&quot;eric&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;,dog,fish,llama&quot;</span>, catFreeMenagerie<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        Assert.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;cat,dog,,llama&quot;</span>, beeFreeMengerie<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>However, if StringReplace() had the side effect of also changing the passed in haystack, then the second Assert would fail, because the first StringReplace has the unexpected side effect of changing one of its arguments.</p>
<p>Evans in the DDD book has quite a bit to say about this; arguing that <a href="http://my.safaribooksonline.com/0321125215/ch10lev1sec2" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://my.safaribooksonline.com/0321125215/ch10lev1sec2');">having side effect free functions goes a long way towards making a supple design</a></p>
<p><a href="http://webmat.wordpress.com/2007/12/13/an-easy-way-to-make-your-code-more-testable/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://webmat.wordpress.com/2007/12/13/an-easy-way-to-make-your-code-more-testable/');">Side effect free functions also make testing &#038; refactoring easier</a> (less state to worry about etc)</p>
<p>Remember, function that changes parameters entrusted is rude, and should not be trusted!</p>
<p>PS:  <a href="http://lyrics.doheth.co.uk/songs/monty-python/sings/eric-the-half-a-bee.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://lyrics.doheth.co.uk/songs/monty-python/sings/eric-the-half-a-bee.php');">Eric the half a bee lyrics</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2009/02/25/functions-with-side-effects-are-just-rude/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2009/02/25/functions-with-side-effects-are-just-rude/</feedburner:origLink></item>
		<item>
		<title>Selenium gotcha – selenium.GetHtmlSource() returns processed HTML</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/qYFreNdENz0/</link>
		<comments>http://davidlaing.com/2008/12/29/selenium-gotcha-seleniumgethtmlsource-returns-processed-html/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 18:11:01 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[acceptance test]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[selenium]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=142</guid>
		<description><![CDATA[Whilst writing some Selenium based acceptance tests today; I bumped into a hair pulling gotcha.  Hopefully this post will prevent you from the same pain.
The test was to check whether some tracking tag javascript was being inserted into the page correctly or not.
I assumed that I could get the page source as it was being [...]]]></description>
			<content:encoded><![CDATA[<p>Whilst writing some Selenium based acceptance tests today; I bumped into a hair pulling gotcha.  Hopefully this post will prevent you from the same pain.</p>
<p>The test was to check whether some tracking tag javascript was being inserted into the page correctly or not.</p>
<p>I assumed that I could get the page source as it was being delivered to the browser by calling selenium.GetHtmlSource(); and then check that for the javascript string I was expected.</p>
<p>Unfortunately, GetHtmlSource is just a proxy for the browsers DOM.InnerHTML method; and that returns the Html <strong>after</strong> it has been preprocessed by the browser.</p>
<p>Turns out that preprocessing does a couple of funky things, including</p>
<ul>
<li>Changing line-endings (Firefox)</li>
<li>Changing capitalization (IE6)</li>
<li>Seemingly random removal / insertion of &#8221; &amp; &#8216;  (IE6)</li>
</ul>
<p>So, when I was expecting a string like this:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p14210');">[<span id="p14210_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p142code10'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p14210"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p142code10"><pre class="javascript"><span style="color: #339933;">&lt;</span>script language<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;javascript&quot;</span> type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;!--</span>
   <span style="color: #003366; font-weight: bold;">var</span> amPid <span style="color: #339933;">=</span> <span style="color: #3366CC;">'206'</span><span style="color: #3366CC;">';
   var amPPid = '</span><span style="color: #CC0000;">4803</span><span style="color: #3366CC;">';
   if (document.location.protocol=='</span>https<span style="color: #339933;">:</span><span style="color: #3366CC;">')
...[snip]...
</span</pre></td></tr></table></div>

<p>IE6 was presenting me with:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p14211');">[<span id="p14211_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p142code11'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p14211"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p142code11"><pre class="javascript"><span style="color: #339933;">&lt;</span>SCRIPT language<span style="color: #339933;">=</span>javascript type<span style="color: #339933;">=</span>text<span style="color: #339933;">/</span>javascript<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;!--</span>
   <span style="color: #003366; font-weight: bold;">var</span> amPid <span style="color: #339933;">=</span> <span style="color: #3366CC;">'206'</span><span style="color: #3366CC;">';
   var amPPid = '</span><span style="color: #CC0000;">4803</span><span style="color: #3366CC;">';
   if (document.location.protocol=='</span>https<span style="color: #339933;">:</span><span style="color: #3366CC;">')
...[snip]...
</span</pre></td></tr></table></div>

<p>A possible solution is to ignore case, whitespace and quotes when doing the comparison, with a helper method like this:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p14212');">[<span id="p14212_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p142code12'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p14212"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p142code12"><pre class="csharp"><span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Use this to compare strings to those returned from selenium.GetHtmlSource for an Internet Explore instance</span>
        <span style="color: #008080; font-style: italic;">/// (IE6 seems to change case and inclusion of quotes, especially for Javascript.?)</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;expected&quot;&gt;&lt;/param&gt;</span>
        <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;actual&quot;&gt;&lt;/param&gt;</span>
        <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> AssertStringContainsIgnoreCaseWhiteSpaceAndQuotes<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span> expected, <span style="color: #FF0000;">string</span> actual<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #FF0000;">string</span> expectedClean <span style="color: #008000;">=</span> Regex.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span>expected, <span style="color: #666666;">@&quot;\s&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">ToLower</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\&quot;</span>&quot;</span>,<span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;'&quot;</span>,<span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #FF0000;">string</span> actualClean <span style="color: #008000;">=</span> Regex.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span>actual, <span style="color: #666666;">@&quot;\s&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">ToLower</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\&quot;</span>&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;'&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            StringAssert.<span style="color: #0000FF;">Contains</span><span style="color: #000000;">&#40;</span>expectedClean,actualClean,
                                  <span style="color: #FF0000;">string</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Expected string <span style="color: #008080; font-weight: bold;">\n</span><span style="color: #008080; font-weight: bold;">\n</span>{0} <span style="color: #008080; font-weight: bold;">\n</span><span style="color: #008080; font-weight: bold;">\n</span>is not contained within <span style="color: #008080; font-weight: bold;">\n</span><span style="color: #008080; font-weight: bold;">\n</span>{1}&quot;</span>, expected, actual<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>It was the line endings that really floored me; because they were automatically normalized/corrected by my test runner when displaying the error.  Aaargh!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/12/29/selenium-gotcha-seleniumgethtmlsource-returns-processed-html/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2008/12/29/selenium-gotcha-seleniumgethtmlsource-returns-processed-html/</feedburner:origLink></item>
		<item>
		<title>Apache2 on Ubuntu 8.04LTS; restrict access to PAM authenticated users</title>
		<link>http://feedproxy.google.com/~r/DavidLaing/~3/5RMDhKJhihM/</link>
		<comments>http://davidlaing.com/2008/12/27/apache2-on-ubuntu-804lts-restrict-access-to-pam-authenticated-users/#comments</comments>
		<pubDate>Sat, 27 Dec 2008 19:40:26 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[apache2]]></category>
		<category><![CDATA[pam]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=140</guid>
		<description><![CDATA[I have a couple of static pages that I want to restrict access to.
I don&#8217;t want to manage another set of usernames &#38; passwds, so I&#8217;d like apache2 to authenticate off the standard users on my system, via PAM.
To get this to work, you need to install and configure mod_auth_pam and mod_auth_shadow
aptitude install libapache2-mod-auth-pam libapache2-mod-auth-shadow
Ensure [...]]]></description>
			<content:encoded><![CDATA[<p>I have a couple of static pages that I want to restrict access to.</p>
<p>I don&#8217;t want to manage another set of usernames &amp; passwds, so I&#8217;d like apache2 to authenticate off the standard users on my system, via PAM.</p>
<p>To get this to work, you need to install and configure mod_auth_pam and mod_auth_shadow</p>
<pre>aptitude install libapache2-mod-auth-pam libapache2-mod-auth-shadow</pre>
<p>Ensure the <a href="http://ubuntuforums.org/showthread.php?t=275996" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://ubuntuforums.org/showthread.php?t=275996');">www-data user is part of the shadow group</a>, so apache2 can read the passwords</p>
<pre>usermod -G shadow www-data</pre>
<p>And set up the relevent virtual host:</p>
<pre>
<Directory />
                AuthPAM_Enabled On
                AuthShadow on
                AuthPAM_FallThrough Off
                AuthBasicAuthoritative Off
                AuthType Basic
                AuthName "Restricted to group: sysadmins"
                AuthUserFile /dev/null
                Require group sysadmins</pre>
<p>Restart apache, and you&#8217;re done!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/12/27/apache2-on-ubuntu-804lts-restrict-access-to-pam-authenticated-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://davidlaing.com/2008/12/27/apache2-on-ubuntu-804lts-restrict-access-to-pam-authenticated-users/</feedburner:origLink></item>
	</channel>
</rss>
