<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>hackification.com</title>
	<atom:link href="http://www.hackification.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hackification.com</link>
	<description>Rediscover the joy of coding.</description>
	<lastBuildDate>Sun, 07 Feb 2010 12:29:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Weekly Links &#8211; node.js, Processors, Microsoft, and more</title>
		<link>http://www.hackification.com/2010/02/07/weekly-links/</link>
		<comments>http://www.hackification.com/2010/02/07/weekly-links/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 12:24:33 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=422</guid>
		<description><![CDATA[Since I&#8217;m having trouble producing full-length articles at the moment, I thought I&#8217;d try a different track to at least get some value out of my blog hosting costs. I&#8217;ll try to post a handful of links that have caught my attention each week.

Comet with node.js and V8
http://amix.dk/blog/post/19484
A presentation (slideshow, no audio or video) on [...]]]></description>
			<content:encoded><![CDATA[<p>Since I&#8217;m having trouble producing full-length articles at the moment, I thought I&#8217;d try a different track to at least get <em>some </em>value out of my blog hosting costs. I&#8217;ll try to post a handful of links that have caught my attention each week.</p>
<p><span id="more-422"></span></p>
<h3>Comet with node.js and V8</h3>
<p><a href="http://amix.dk/blog/post/19484" target="_blank">http://amix.dk/blog/post/19484</a></p>
<p>A presentation (slideshow, no audio or video) on node.js, a JavaScript web-server running on Google&#8217;s V8 engine. Very interesting concept &#8211; using an event-based system vastly simplifies the code needed to server data. There&#8217;s plenty of discussion about node.js on the interwebs at the moment &#8211; hopefully it will grow and become more than just a curiosity.</p>
<h3>Gallery  of Processor Cache Effects</h3>
<p><a href="http://igoro.com/archive/gallery-of-processor-cache-effects/" target="_blank">http://igoro.com/archive/gallery-of-processor-cache-effects/</a></p>
<p>Interesting blog post about the effects that processor caches may have on performance. Examples are in C#, but really apply to any language.</p>
<h3>Microsoft’s Creative Destruction</h3>
<p><a href="http://www.nytimes.com/2010/02/04/opinion/04brass.html?pagewanted=1&amp;ref=opinion" target="_blank">http://www.nytimes.com/2010/02/04/opinion/04brass.html?pagewanted=1&amp;ref=opinion</a></p>
<p>Opinion piece from the NYTimes regarding Microsoft&#8217;s recent lack of innovation (at least, in the area of shiny gadgets). Written by an ex-vice-president of Microsoft.</p>
<h3>How Many Passes?</h3>
<p><a href="http://blogs.msdn.com/ericlippert/archive/2010/02/04/how-many-passes.aspx" target="_blank">http://blogs.msdn.com/ericlippert/archive/2010/02/04/how-many-passes.aspx</a></p>
<p>Summary article from Eric Lippert describing the differences between the C# compiler and a &#8220;traditional&#8221; compiler, and listing the various passes made over the symbol tree.</p>
<h3>A Deadlock Holiday</h3>
<p><a href="http://www.theregister.co.uk/2009/12/10/verity_stob/" target="_blank">http://www.theregister.co.uk/2009/12/10/verity_stob/</a></p>
<p>Very funny tongue-in-cheek article about the current state of parallel / multicore coding techniques, from Verity Stob of The Register.</p>
<h3>A Maturity Model for Source Control</h3>
<p><a href="http://lucas-ward.blogspot.com/2010/02/maturity-model-for-source-control-scmm.html" target="_blank">http://lucas-ward.blogspot.com/2010/02/maturity-model-for-source-control-scmm.html</a></p>
<p>Semi-opinion piece assigning levels to types of source-control systems &#8211; from &#8220;No SCM&#8221; through &#8220;Clunky&#8221; to &#8220;Speedy,  Invisible, and Highly Capable&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2010/02/07/weekly-links/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.less &#8211; Dot Less Dynamic CSS Processor for .NET</title>
		<link>http://www.hackification.com/2010/01/17/less-dot-less-dynamic-css-processor-for-net/</link>
		<comments>http://www.hackification.com/2010/01/17/less-dot-less-dynamic-css-processor-for-net/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 18:49:26 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[less]]></category>
		<category><![CDATA[stylesheets]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=377</guid>
		<description><![CDATA[Of the three textual formats that make up the main pillars of web development (HTML, CSS, and JavaScript), CSS has had the least attention in terms of server-side processing. HTML is obviously well covered, with frameworks such as ASP.NET. JavaScript is starting to be covered with compilers such as Google&#8217;s Closure Tools. Until now however [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-379" style="margin-right: 10px;" title=".less" src="http://www.hackification.com/wp-content/uploads/2010/01/dotless.jpg" alt=".less logo" width="131" height="69" />Of the three textual formats that make up the main pillars of web development (HTML, CSS, and JavaScript), CSS has had the least attention in terms of server-side processing. HTML is obviously well covered, with frameworks such as ASP.NET. JavaScript is starting to be covered with compilers such as <a title="Closure Tools - Google Code" href="http://code.google.com/closure/" target="_blank">Google&#8217;s Closure Tools</a>. Until now however (in the .NET world at least), there haven&#8217;t really been any CSS processors.</p>
<p><span id="more-377"></span>Luckily, that is now changing with the recent release of <a title="Less Css for .NET" href="http://www.dotlesscss.com/" target="_blank">.less (Dot Less)</a>. This is a port of the Ruby LESS library to .NET. It&#8217;s still in beta, so be warned that the API is still in a certain amount of flux. (That&#8217;s a good thing however &#8211; I&#8217;d rather have a bit of pain in the beta stage, in return for a well-thought-out API later on). The authors are very responsive &#8211; there&#8217;s a friendly <a title="DotLess (Less Css for .NET) | Google Groups" href="http://groups.google.com/group/dotless" target="_blank">discussion group</a> &#8211; and the couple of bugs I&#8217;ve reported have been fixed within a very short time frame. This project seems to be in very active development, and I&#8217;m extremely impressed with it. It&#8217;s so simple to use, and gives CSS development a much-needed shot in the arm, that using this library seems a no-brainer decision to me.</p>
<p>So what benefits does this library give you? (Examples are taken from the .less homepage).</p>
<h3>1. Minification</h3>
<p>The final output from .less is a compacted (or minified) version. This means you can write your CSS with as many comments and whitespace as you like, without worrying that the client-side download will be huge. This might seem like a &#8220;meh&#8221; feature, but it&#8217;s free and will have immediate beneficial effects on your bandwidth.</p>
<h3>2. Variables</h3>
<p>CSS doesn&#8217;t support any form of variables or macros, so constants (the worst culprit being colours) get copied around the CSS file. That&#8217;s fine until you decide that the pink-on-orange colour scheme isn&#8217;t working, and you need to make a change. .less allows you to define variables using the syntax &#8220;@name: value&#8221;, and then reference them anywhere a value would otherwise be used.</p>
<p>Example:</p>
<pre>@brand_color: #4D926F;

#header {
  color: @brand_color;
}

h2 {
  color: @brand_color;
}</pre>
<h3>3. Mixins</h3>
<p>We&#8217;re now in a second round of &#8220;browser wars&#8221;, with modern browsers providing useful features such as border-radius via non-standard extensions. We also have to cope with Internet Explorer still making use of odd syntax for features such as opacity (via filter). The upshot of this is that to define certain CSS effects, we have to provide three or four CSS style properties, to cover various browsers. Mixins allow this bloat to be ameliorated by defining a class with the desired properties, and then &#8220;mixing&#8221; them into another class.</p>
<p>Example:</p>
<pre>.rounded_corners {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}</pre>
<h3>4. Nested Rules</h3>
<p>This feature is probably of least interest to me, since I favour single-line rule formatting, however if you write multi-line rules, then this could be a very useful feature. Nested rules allow &#8220;inheritance&#8221; of CSS rules, such that more specific rules may be nested within a less-specific parent rule.</p>
<p>Example:</p>
<pre>#header {
  color: red;
  a {
       font-weight: bold;
       text-decoration: none;
    }
}</pre>
<p>I could possibly see myself using it for :hover rules and the like.</p>
<h3>5. Operations</h3>
<p>Since I&#8217;m merging .less into an existing codebase, I haven&#8217;t yet refactored my CSS to make use of this feature. Operations allow arithmetic to be performed on expressions involving variables. For example, instead of defining variables for a colour and its lighter equivalent, you can instead just define a variable for the colour, and then computer the lighter colour.</p>
<p>Example:</p>
<pre>@the-border: 1px;
@base-color: #111;

#header {
  color: @base-color * 3;
  border-left: @the-border;
  border-right: @the-border * 2;
}

#footer {
  color: (@base-color + #111) * 1.5;
}</pre>
<h3>Alternative Usage</h3>
<p>The homepage gives instructions for a quick-up-and-running scenario, however I already had code to handle caching and combining of stylesheets, so I wanted to hook into that. It&#8217;s easily possible to process CSS as strings if desired:</p>
<pre>// .less format CSS as string in 'input'.
var dotLessEngine = new dotless.Core.engine.ExtensibleEngineImpl( input );

// Transformed CSS now in 'css'.
var css = dotLessEngine.Css;

// Now minify...
var dotlessMinifier = new dotless.Core.minifier.Processor( css );

// Output CSS suitable for sending to client in 'output'.
var output = new string( dotlessMinifier.Output );</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2010/01/17/less-dot-less-dynamic-css-processor-for-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8216;Smart and Gets Things Done&#8217; vs &#8216;Done and Gets Things Smart&#8217;</title>
		<link>http://www.hackification.com/2010/01/10/smart-and-gets-things-done-vs-done-and-gets-things-smart/</link>
		<comments>http://www.hackification.com/2010/01/10/smart-and-gets-things-done-vs-done-and-gets-things-smart/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 19:10:47 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[Links]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[articles]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[recruitment]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=351</guid>
		<description><![CDATA[In this article I link to two excellent articles on the subject of hiring coders. They&#8217;re not new by any means, but if you haven&#8217;t read one or both of them, I thoroughly recommend them. (If you&#8217;re familiar with both these writers, then skip this article.)

Smart, and Gets Things Done
Joel Spolsky&#8217;s 2006 article &#8220;The Guerrilla [...]]]></description>
			<content:encoded><![CDATA[<p>In this article I link to two excellent articles on the subject of hiring coders. They&#8217;re not new by any means, but if you haven&#8217;t read one or both of them, I thoroughly recommend them. (If you&#8217;re familiar with both these writers, then skip this article.)</p>
<p><span id="more-351"></span></p>
<h3>Smart, and Gets Things Done</h3>
<p><a href="http://www.hackification.com/wp-content/uploads/2010/01/spolsky.jpg"><img class="alignleft size-full wp-image-363" style="margin-right: 10px;" title="Joel Spolsky" src="http://www.hackification.com/wp-content/uploads/2010/01/spolsky.jpg" alt="" width="130" height="87" /></a>Joel Spolsky&#8217;s 2006 article &#8220;The Guerrilla Guide to Interviewing&#8221; is a real classic that&#8217;s since been made into a book. He argues that there are two things to look for when interviewing, and that a candidate needs to have both attributes &#8211; having just one is as bad as having neither.</p>
<blockquote><p>&#8220;Everybody gives lip service to the idea that people are the most important part of a software project, but nobody is quite sure what you can <em>do</em> about it. The very first thing you have to do right if you want to have good programmers is to <em>hire</em> the right programmers, and that means you have to be able to figure out who the right programmers <em>are</em>, and this is usually done in the interview process.&#8221;</p></blockquote>
<p>Read Joel&#8217;s Article: <strong><a title="The Guerrilla Guide to Interviewing (version 3.0)" href="http://www.joelonsoftware.com/articles/GuerrillaInterviewing3.html" target="_blank">The Guerrilla Guide to Interviewing (version 3.0)</a></strong></p>
<h3>Done, and Gets Things Smart</h3>
<p><a href="http://www.hackification.com/wp-content/uploads/2010/01/yegge.jpg"><img class="alignleft size-full wp-image-364" style="margin-right: 10px;" title="Steve Yegge" src="http://www.hackification.com/wp-content/uploads/2010/01/yegge.jpg" alt="" width="130" height="87" /></a>Steve Yegge&#8217;s 2008 response article reminds us that recognising smarts (in ourselves and others) isn&#8217;t even necessarily possible. He suggests that the best approach to hiring is finding &#8220;seed&#8221; employees (although obviously being able to identify them is a Catch-22 situation). To find them you either need to be lucky, or perhaps home in on them via word of mouth.</p>
<blockquote><p>&#8220;How do you hire someone who&#8217;s smarter than you?  How do you <em>tell</em> if someone&#8217;s smarter than you? This is a problem I&#8217;ve thought about, over nearly twenty years of interviewing, and it appears that the answer is: you can&#8217;t. You just have to get lucky.&#8221;</p></blockquote>
<p>Read Steve&#8217;s Article: <strong><a title="Done, and Gets Things Smart" href="http://steve-yegge.blogspot.com/2008/06/done-and-gets-things-smart.html" target="_blank">Done, and Gets Things Smart</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2010/01/10/smart-and-gets-things-done-vs-done-and-gets-things-smart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick Tip: Avoid Enums If Possible</title>
		<link>http://www.hackification.com/2009/12/01/quick-tip-avoid-enums-if-possible/</link>
		<comments>http://www.hackification.com/2009/12/01/quick-tip-avoid-enums-if-possible/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 18:16:43 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[enums]]></category>
		<category><![CDATA[oo]]></category>
		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=330</guid>
		<description><![CDATA[One of the &#8220;anti-patterns&#8221; I come across from time to time is over-use of enumerations for control flow. This article describes why I consider it an anti-pattern, and how to counteract it.
Let&#8217;s suppose we want to represent an arithmetic operation on two numbers &#8211; such as plus, minus, multiply, etc. We could represent that operation [...]]]></description>
			<content:encoded><![CDATA[<p>One of the &#8220;anti-patterns&#8221; I come across from time to time is over-use of enumerations for control flow. This article describes why I consider it an anti-pattern, and how to counteract it.</p>
<p><span id="more-330"></span>Let&#8217;s suppose we want to represent an arithmetic operation on two numbers &#8211; such as plus, minus, multiply, etc. We could represent that operation as an enum (although to be clear &#8211; I don&#8217;t think you should):</p>
<pre>enum ArithmeticOperation
{
  Add,
  Subtract,
  Multiply,
  Divide
}</pre>
<p>We could then define a function to apply this operation to two numbers (highlighting will be explained later):</p>
<pre>int ApplyOperation(ArithmeticOperation op, int x, int y)
{
  switch(op)
  {
    <span style="color: #ffff00;">case ArithmeticOperation.Add: return x + y;</span>
    case ArithmeticOperation.Subtract: return x - y;
    case ArithmeticOperation.Multiply: return x * y;
    case ArithmeticOperation.Divide: return x / y;
    default: throw new InvalidOperationException();
  }
}</pre>
<p>That&#8217;s&#8230; sort of fine &#8211; but what happens when we want to extend it?</p>
<p><strong>Adding Operators: No Compile-Time Checking</strong></p>
<p>Let&#8217;s consider what happens if we want to add another operator &#8211; say exponentiation. If we add the enum value but forget to implement the switch case value, everything compiles fine. It&#8217;s only once we come to run the code, and actually hit that code path, that we discover the mistake, giving a run-time exception.</p>
<p><strong>Adding Methods: Bad Code Organisation</strong></p>
<p>Next, imagine what happens if we need to add more methods that switch on this enum. We might need a method returning the operator symbol, and another returning the operator precedence.</p>
<pre>string GetOperatorSymbol(ArithmeticOperation op)
{
  switch(op)
  {
    <span style="color: #ffff00;">case ArithmeticOperation.Add: return "+";</span>
    case ArithmeticOperation.Subtract: return "-";
    case ArithmeticOperation.Multiply: return "*";
    case ArithmeticOperation.Divide: return "/";
    default: throw new InvalidOperationException();
  }
}

int GetOperatorPrecedence(ArithmeticOperation op)
{
  switch(op)
  {
    <span style="color: #ffff00;">case ArithmeticOperation.Add: return 10;</span>
    case ArithmeticOperation.Subtract: return 10;
    case ArithmeticOperation.Multiply: return 20;
    case ArithmeticOperation.Divide: return 20;
    default: throw new InvalidOperationException();
  }
}</pre>
<p>I&#8217;ve highighted the relevant code for the &#8220;add&#8221; operator. Notice how it&#8217;s spread all over the place. Switch statements might group by operation, but they split by concept &#8211; and that&#8217;s the exact opposite of what&#8217;s usually intended with OO coding.</p>
<p><strong>A Better Way</strong></p>
<p>I&#8217;d suggest a better way of approaching this problem is to use an abstract class.</p>
<pre>abstract class ArithmeticOperation
{
  abstract int ApplyOperation(int x, int y);
  abstract string GetSymbol();
  abstract int GetPrecendence();
}

class AddArithmeticOperation : ArithmeticOperation
{
  override int ApplyOperation(int x, int y)
  {
    return x + y;
  }

  override string GetSymbol()
  {
    return "+";
  }

  override int GetPrecedence()
  {
    return 10;
  }
}

// ...and so forth for the other operators.</pre>
<p>That way, all the code for each operator sits in the same place, and adding any new methods for an operator requires all operators to be implemented before the code will even compile.</p>
<p><strong>When to Use Enums</strong></p>
<p>So if enums should be avoided, why do most languages include them? Personally I&#8217;d be happy without them,  but I can think of one possible reason you might want to use an enum. If you&#8217;re defining a public interface designed for consumption by other coders, you could argue that simplifying the interface at the expense of the code inside is a valid trade-off.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2009/12/01/quick-tip-avoid-enums-if-possible/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ten IT Concepts That Non-IT People Don&#8217;t Get</title>
		<link>http://www.hackification.com/2009/09/28/ten-it-concepts-that-non-it-people-dont-get/</link>
		<comments>http://www.hackification.com/2009/09/28/ten-it-concepts-that-non-it-people-dont-get/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 20:40:24 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[Opinion]]></category>
		<category><![CDATA[it]]></category>
		<category><![CDATA[support]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=243</guid>
		<description><![CDATA[Since I &#8220;work with computers&#8221; I tend to get asked to do fair amount of unofficial technical support for family and neighbours. I&#8217;ve noticed that the same confusions about IT crop up again and again. Here&#8217;s my top ten.
(Note that due to my background this is going to be Windows-centric. Please don&#8217;t take this to [...]]]></description>
			<content:encoded><![CDATA[<p>Since I &#8220;work with computers&#8221; I tend to get asked to do fair amount of unofficial technical support for family and neighbours. I&#8217;ve noticed that the same confusions about IT crop up again and again. Here&#8217;s my top ten.</p>
<p><span id="more-243"></span>(Note that due to my background this is going to be Windows-centric. Please don&#8217;t take this to mean that I think Windows PCs are unfriendly &#8211; it&#8217;s just I don&#8217;t know enough about other systems to be able to comment. I also don&#8217;t want to come across as elitist &#8211; if non-IT people don&#8217;t understand something, that&#8217;s not because they&#8217;re dumb &#8211; it&#8217;s because we haven&#8217;t made computer systems obvious enough.)</p>
<p><strong><img class="alignleft size-full wp-image-308" title="Click or Double-Click" src="http://www.hackification.com/wp-content/uploads/2009/09/mouse-click.jpg" alt="Click or Double-Click" width="100" height="100" />1. When to Click and When to Double-Click</strong></p>
<p>This one is a continual source of annoyance to IT people, and especially to those in support. It seems obvious to us which should be used when, but before you get mad with the user you&#8217;re helping, consider this: can you make rules for when to click and when to double-click? Why do you double-click an icon to perform the action, but only single-click a button? What if Windows is set to &#8220;single click to open an item&#8221;?</p>
<p>Add into the mix the close cousin right-clicking, together with triple-clicks in text editors, double-single-clicks to rename, and of course modified clicks (holding down control or shift), and I think confusion is the correct response.</p>
<p><strong><img class="alignleft size-full wp-image-311" title="Folder" src="http://www.hackification.com/wp-content/uploads/2009/09/folder.jpg" alt="Folder" width="100" height="100" />2. Hierarchical Folders</strong></p>
<p>Hierarchical folders are a great idea &#8211; don&#8217;t get me wrong &#8211; but they&#8217;re a good example of a neat metaphor overextended and hence confused. Most people are familiar with cardboard folders that can store bits of paper &#8211; and equally most people are happy to store their files in folders on their PC. Where it all goes wrong is with folders within folders, as this very rarely happens in the real world. Many users are simply unaware that they can create additional folders inside &#8220;My Documents&#8221; &#8211; hence the usual tendency to find hundreds or even thousands of files, all at the same folder level.</p>
<p>Making the problem even worse is the fact that &#8220;Save As&#8221; and &#8220;Open&#8221; dialogs often look nothing like the standard file explorer. This makes it more difficult to mentally link the save operation with the save location. This leads to the common problem of a user &#8220;losing&#8221; all their files &#8211; when in fact the &#8220;open&#8221; dialog has for some reason defaulted to another directory, and hence shows a different list of files to those the user was expecting.</p>
<p>(And don&#8217;t even get me started on the fact that folders like &#8220;My Documents&#8221; appear in TWO locations in the folder tree &#8211; the physical one that users can&#8217;t find or recognise, and the virtual one which isn&#8217;t supported by all applications).</p>
<p><strong><img class="alignleft size-full wp-image-313" title="Recycle" src="http://www.hackification.com/wp-content/uploads/2009/09/recycle.jpg" alt="Recycle" width="100" height="100" />3. Using Add/Remove Programs</strong></p>
<p>I need to clarify here. When a user wants to remove a program they chose to install, they head over to Add/Remove Programs &#8211; no problems. I&#8217;ve found however that when it&#8217;s software they didn&#8217;t install (or didn&#8217;t intentionally install) &#8211; there&#8217;s a problem. Messages that pop-up on start-up, unwanted system tray announcements, even auto-starting applications &#8211; these are all a source of annoyance, and often there&#8217;s no obvious way to associate the offender with the appropriate entry in Add/Remove Programs. Often trialware pops up nag screens at startup, giving the user the option to purchase it &#8211; but without an option to uninstall.</p>
<p>Even worse is the case where a user wants to keep the application, just not have it launch at startup. There are many different ways an application can hook into the startup sequence, and most of them are inaccessible unless you&#8217;re comfortable using something like msconfig (which, let&#8217;s face it, non-IT people aren&#8217;t).</p>
<p><strong><img class="alignleft size-full wp-image-315" title="Sony Vaio" src="http://www.hackification.com/wp-content/uploads/2009/09/vaio.jpg" alt="Sony Vaio" width="100" height="68" />4. Installing Bundled Software Hurts</strong></p>
<p>IT people know that bundled software (aka &#8220;crapware&#8221;) isn&#8217;t included for our benefit &#8211; it&#8217;s generally a way hardware manufactures or system builders lower costs by basically pushing unwanted adverts for unwanted products onto your machine, in the hope that you won&#8217;t be able to uninstall them, and will finally buy them (see item #3 above).</p>
<p>Unfortunately a standard user assumes that if a hardware item comes with a disk, that disk is there for a good reason &#8211; and so installs the lot. Sometimes this is just an annoyance, but sometimes it&#8217;s more sinister &#8211; bundled software often stops the PC functioning correctly. The worst offenders seem to be the software that comes with wireless network adapters. For some reason they all want to turn off Window&#8217;s standard wireless zero-configuration system, and install their own. Sadly, their own offerings often don&#8217;t work (especially if they were written pre-XP) and the user is left with a completely non-functioning wireless system. Had the user simply plugged in the hardware and let Windows do the rest, it probably would have worked. The instructions said to install the software &#8211; and possibly stung by all the geeks who kept telling them to &#8220;RTFM&#8221; &#8211; they did so.</p>
<p><strong><img class="alignleft size-full wp-image-318" title="Firefox" src="http://www.hackification.com/wp-content/uploads/2009/09/firefox.jpg" alt="Firefox" width="100" height="100" />5. That There Is A Choice Of Software</strong></p>
<p>Odds are that you&#8217;re reading this on Firefox &#8211; or if not, as a reader of a coding blog, you at least know the name of the browser you&#8217;re using. This almost certainly isn&#8217;t the case for the majority of PC users &#8211; they don&#8217;t use a <em>browser</em>, they use <em>the internet</em> (or if not the internet, then they use <em>msn, facebook, google,</em> or whatever). Most people simply use the browser as a means to an end. The same goes for music players, email clients (generally dictated by their ISP), and anti-virus (generally the one with the biggest display in the local PC shop).</p>
<p>Unfortunately this means that when things go wrong, or go expensive, or go ad-ridden, these users aren&#8217;t even aware they can change. Adverts on the web are annoying, but if you have no idea you can change your browser and install an ad-blocker, you have no choice but to suffer them. This also means that poor software can survive in the marketplace &#8211; since for correctly positioned, pushed, and marketed software, there ceases to even be a marketplace.</p>
<p><strong><img class="alignleft size-full wp-image-320" title="Windows Update" src="http://www.hackification.com/wp-content/uploads/2009/09/update.jpg" alt="Windows Update" width="100" height="100" />6. What Updates Do</strong></p>
<p>While writing this article &#8211; the first two weeks of September &#8211; my laptop has installed updates on the 1st, 4th, 9th, 11th and 14th of the month. Since this is a rather slow laptop, that means that if I choose to install them, I have to put up with bad performance, and if I don&#8217;t, I have to put up with repeated nagging. Even when I do install them, I know that in another couple of days they&#8217;ll be back.</p>
<p>I know updates are necessary &#8211; but do we need them every three days? Do they need to be quite so slow? And do they have to nag when I&#8217;m trying to use my PC &#8211; couldn&#8217;t they wait a while to see if the screensaver kicks in, as that&#8217;s likely to be a better time than now, now, now.</p>
<p><strong><img class="alignleft size-full wp-image-322" title="Money" src="http://www.hackification.com/wp-content/uploads/2009/09/money.jpg" alt="Money" width="100" height="112" />7. Software Licensing</strong></p>
<p>We need to put aside a discussion of whether software should be free or not for this one, and let&#8217;s just assume that people are happy paying for software for now.</p>
<p>The problem is that buying software isn&#8217;t really like buying other goods &#8211; what you buy isn&#8217;t the box, or the media, but a license. With normal goods, once you&#8217;ve purchased it, you keep hold it, and if it turns out to be an illegal purchase, someone (eg the police) have to come and physically remove it. With software, if the vendor decides it&#8217;s not a valid purchase, then the software magically stops working, with no easy recourse for the customer.</p>
<p>I&#8217;ve come across many cases of people who thought they were legitimately purchasing software, but in fact weren&#8217;t &#8211; either purchasing from someone who was knowingly selling illegal software, or purchasing from someone who believed they had the right to sell, but didn&#8217;t. Either way, the honest software purchasers had no immediate way of knowing the software they were buying wasn&#8217;t legit.</p>
<p>To be fair, most software vendors are taking steps to improve this &#8211; although the cynic in me says this is mainly to protect revenue streams, not customers.</p>
<p><strong><img class="alignleft size-full wp-image-324" title="RAM" src="http://www.hackification.com/wp-content/uploads/2009/09/ram.jpg" alt="RAM" width="100" height="64" />8. What Memory (RAM) Is For</strong></p>
<p>I think most computer users have a pretty good idea what disk storage is for &#8211; that&#8217;s where their files are stored. What I think users have a bigger problem with is volatile memory. It&#8217;s very difficult to describe to a non-techie what RAM actually does &#8211; just saying &#8220;it&#8217;s what running programs use&#8221; doesn&#8217;t give a full description by any means.</p>
<p>Making the problem worse is that fact that most consumer PCs are sold with the bare minimum of RAM. Users can easily see that they have a good amount of disk storage free, but it&#8217;s more difficult to get a feeling for whether they have enough RAM. Most users simply don&#8217;t realise that computers don&#8217;t have to be slow, and don&#8217;t have to spend all their time swapping virtual memory.</p>
<p><strong><img class="alignleft size-full wp-image-326" title="Network" src="http://www.hackification.com/wp-content/uploads/2009/09/network.jpg" alt="Network" width="100" height="90" />9. How To Use Networking</strong></p>
<p>As computers become cheaper, many households now have more than one. As that happens, this question is asked of me more and more often: &#8220;I&#8217;ve saved my files on the office computer; how can I get them on the laptop?&#8221;. The first couple of times, I set up a simple home network and created shortcuts to shared folders on each desktop. Unfortunately, this didn&#8217;t really cut it.</p>
<p>I think the main problem is that home networking fundamentally doesn&#8217;t fit in with most people&#8217;s work patterns &#8211; if they&#8217;re working on the laptop (say), why would the office computer be switched on? Having to leave both computers on just doesn&#8217;t fit. From the user&#8217;s point of view, sometimes the files are there (when the other computer is on), and sometimes they&#8217;re not.</p>
<p>I&#8217;ve found that solutions like <a href="http://www.getdropbox.com/" target="_blank">Dropbox</a> are much more palatable &#8211; while all the home computers might not be switched on, the internet connection almost always is. The networking in this case is transparent &#8211; the user doesn&#8217;t have to do a thing &#8211; and the files are magically up-to-date on all their computers.</p>
<p><strong><img class="alignleft size-full wp-image-327" title="Computer" src="http://www.hackification.com/wp-content/uploads/2009/09/computer.jpg" alt="Computer" width="100" height="80" />10. The Display Is Not The Computer</strong></p>
<p>For a long time, the sheer size of CRT monitors led many users to assume the monitor <em>was</em> the computer, and if they thought about the box below the desk at all, they thought it was &#8220;the hard-drive&#8221;. Now that monitors are much slimmer, people understand that the monitor is just a display mechanism, and the computer actually is under the desk.</p>
<p>Where it all goes a little confusing is when the computer in question isn&#8217;t near the display in front of the user &#8211; remote desktop, remote assistance, and the like. Even more flummoxing seems to be the notion of servers in general &#8211; for some reason a computer without a display unit doesn&#8217;t seem to be easily understandable. Despite the familiarity of the web, the idea that accessing a website involves a computer, often running a familar operating system, somewhere remote, seems a difficult one.</p>
<p><strong>Any More?</strong></p>
<p>Have I missed any other concepts that are repeatedly misunderstood? Any common problems you have to deal with? Let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2009/09/28/ten-it-concepts-that-non-it-people-dont-get/feed/</wfw:commentRss>
		<slash:comments>64</slash:comments>
		</item>
		<item>
		<title>Resizing Single-Image-Rollovers Using jQuery</title>
		<link>http://www.hackification.com/2009/09/02/resizing-single-image-rollovers-using-jquery/</link>
		<comments>http://www.hackification.com/2009/09/02/resizing-single-image-rollovers-using-jquery/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 14:28:00 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[rollovers]]></category>
		<category><![CDATA[sprites]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=252</guid>
		<description><![CDATA[In this article I describe how to create shaped buttons in HTML/CSS that size to their content, have roll-over state, and require only a single image, using jQuery.

I&#8217;m sure most web developers know about image rollovers (using separate images for normal and &#8220;hover&#8221; states of anchors). Hopefully also the use of &#8220;CSS Sprites&#8221; is becoming [...]]]></description>
			<content:encoded><![CDATA[<p>In this article I describe how to create shaped buttons in HTML/CSS that size to their content, have roll-over state, and require only a single image, using jQuery.</p>
<p><span id="more-252"></span></p>
<p>I&#8217;m sure most web developers know about image rollovers (using separate images for normal and &#8220;hover&#8221; states of anchors). Hopefully also the use of &#8220;<a href="http://www.alistapart.com/articles/sprites" target="_blank">CSS Sprites</a>&#8221; is becoming better known &#8211; combining the normal and rollover images into a single physical image file to speed up load times and reduce flicker. I won&#8217;t cover those techniques here.</p>
<p>However, if you want the anchor or button to size to its contents, it&#8217;s more difficult to make use of these techniques. Here&#8217;s one way.</p>
<p><img class="aligncenter size-full wp-image-258" title="Sizing Rollovers" src="http://www.hackification.com/wp-content/uploads/2009/09/SizingRollovers.png" alt="Sizing Rollovers" width="414" height="127" /></p>
<p style="text-align: center;"><em>(The final result &#8211; <a href="http://www.hackification.com/jquery-examples/sizing-rollovers/sizing-rollovers.htm" target="_blank">view demo</a>).</em></p>
<p><strong>Start With Markup</strong></p>
<p>Before diving into fancy techniques, get the markup down as you would like it, if you didn&#8217;t have to style anything.</p>
<pre>&lt;a href="..." class="rollover"&gt;Button Text&lt;/a&gt;</pre>
<p>Ideally we want the markup to be clean and not compromised by styling requirements.</p>
<p><strong>Handle Degradation Gracefully</strong></p>
<p>My technique is going to make use of JavaScript, so let&#8217;s handle the case where the user has it disabled for some reason. Here&#8217;s some very basic CSS to give the button a simple style:</p>
<pre>a.rollover
{
  background-color: #00f;
  border: solid 1px #000;
  color: #fff;
  font-weight: bold;
  padding: 4px;
  text-decoration: none;
}

a.rollover:hover
{
  background-color: #008;
}</pre>
<p><strong>Add Styling Naively</strong></p>
<p>Next, I&#8217;m going to add some rollover styling &#8211; but in a way that isn&#8217;t complete. Firstly I created a simple rollover image, but made it very wide &#8211; it needs to be at least as wide as the widest button is ever going to be:</p>
<p><img class="aligncenter size-full wp-image-256" title="Button Rollover" src="http://www.hackification.com/wp-content/uploads/2009/09/buttons.png" alt="Button Rollover" width="657" height="123" /></p>
<p>I&#8217;m going to define my rollover styling against a class selector of &#8220;extra&#8221; &#8211; you&#8217;ll see where that comes from in a moment.</p>
<pre>a.rollover.extra
{
  background: url(buttons.png) repeat-x left 0;
  border: none;
  height: 27px;
  padding: 23px 40px 10px 40px;
  position: relative;
}

a.rollover.extra:hover
{
  background-position: left -57px;
}</pre>
<p>Note that we&#8217;ve had to undo some of the styles applied previously, such as border.</p>
<p>We&#8217;re kind of getting there, but our buttons won&#8217;t look correct on the right-hand-side.</p>
<p><strong>Use JavaScript To Add Styling Markup</strong></p>
<p>To fix the right-hand end-caps, we need to modify our markup. However, I really don&#8217;t want to have to do that on my pages &#8211; afterall, I might change my mind about the site styling.</p>
<p>Here I recommend using JavaScript to tweak at runtime the markup to what we need. I&#8217;m going to use jQuery for this:</p>
<pre>$(function() {
  $('.rollover')
    .addClass('extra')
    .append('&lt;div class="cap"&gt;&lt;/div&gt;');
});</pre>
<p>Basically, when the pad is ready, I find all elements with class &#8220;rollover&#8221;, add another class (&#8220;extra&#8221;), and append into the rollover button an empty span element which has a class of &#8220;cap&#8221;.</p>
<p>That class &#8220;extra&#8221; triggers the image rollovers. The &#8220;cap&#8221; span can be styled as follows:</p>
<pre>a.rollover.extra .cap
{
  background: url(buttons.png) no-repeat right 0;
  height: 100%;
  position: absolute;
  right: 0;
  top: 0;
  width: 40px;
}

a.rollover.extra:hover .cap
{
  background-position: right -57px;
}</pre>
<p>And voila!</p>
<blockquote><p><a href="http://www.hackification.com/jquery-examples/sizing-rollovers/sizing-rollovers.htm" target="_blank">If you&#8217;d like to see this technique in action, please view the demo</a>.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2009/09/02/resizing-single-image-rollovers-using-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HOWTO: Fix Windows Explorer After Installing Internet Explorer 8</title>
		<link>http://www.hackification.com/2009/07/10/howto-fix-windows-explorer-after-installing-internet-explorer-8/</link>
		<comments>http://www.hackification.com/2009/07/10/howto-fix-windows-explorer-after-installing-internet-explorer-8/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 17:53:43 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[ie8]]></category>
		<category><![CDATA[internet explorer 8]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=236</guid>
		<description><![CDATA[I wrote an article about this problem a while back &#8211; but it seems that the fix is relevant to more than just 64-bit installs of Vista, so I thought I&#8217;d re-release it in the hope that it reaches and helps a few more people.

Unfortunately, it seems that installing Internet Explorer 8 (IE8) sometimes has [...]]]></description>
			<content:encoded><![CDATA[<p><em>I wrote an <a href="http://www.hackification.com/2009/04/01/howto-repair-your-vista-64-bit-system-after-internet-explorer-8/" target="_blank">article</a> about this problem a while back &#8211; but it seems that the fix is relevant to more than just 64-bit installs of Vista, so I thought I&#8217;d re-release it in the hope that it reaches and helps a few more people.</em></p>
<p><span id="more-236"></span></p>
<p>Unfortunately, it seems that installing Internet Explorer 8 (IE8) sometimes has some adverse affects on other applications. Here’s how to fix this.</p>
<p>The problems we’ve experienced following installation of IE8 have been:</p>
<ul>
<li>Windows Explorer opens folders in new windows, even if you have “Open each window in the same folder” checked;</li>
<li>“Open in new tab” doesn’t work in IE8;</li>
<li>Can’t connect to databases using SQL Management Studio Express 2008 (”Unable to cast COM object of type ‘System.__ComObject’ to interface type ‘Microsoft.VisualStudio.OLE.Interop.IServiceProvider’. Exception from HRESULT: 0×80004002 (E_NOINTERFACE)”).</li>
</ul>
<p>The solution is pretty simple:</p>
<ol>
<li>Go to Start -&gt; All Programs -&gt; Accessories, right-click “Command Prompt”, and choose “Run as Administrator”.</li>
<li>OK the user access warning dialogs.</li>
<li>Enter “regsvr32 actxprxy.dll”.</li>
<li>Reboot.</li>
</ol>
<p>Simples! No more tearing my hair out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2009/07/10/howto-fix-windows-explorer-after-installing-internet-explorer-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debug.Assert Considered Pointless</title>
		<link>http://www.hackification.com/2009/06/10/debug-assert-considered-pointless/</link>
		<comments>http://www.hackification.com/2009/06/10/debug-assert-considered-pointless/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 20:26:24 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[assert]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=214</guid>
		<description><![CDATA[One thing I was told as a young programmer was to make good use of assertions for checking code. As time goes by however, I can see less and less use for assertions. I&#8217;m starting to think they&#8217;re pretty useless.

(I&#8217;m going to use C# in my examples here: some of these points might not apply [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-225" style="margin-left: 10px; margin-right: 10px;" title="Debug Assert Stop" src="http://www.hackification.com/wp-content/uploads/2009/06/stop.png" alt="Debug Assert Stop" width="96" height="96" />One thing I was told as a young programmer was to make good use of assertions for checking code. As time goes by however, I can see less and less use for assertions. I&#8217;m starting to think they&#8217;re pretty useless.</p>
<p><span id="more-214"></span></p>
<p>(I&#8217;m going to use C# in my examples here: some of these points might not apply to all languages. By default, an assertion will not fire in a C# release build, and furthermore, the code inside will not even be executed).</p>
<p><em>Update 2009-06-11: I probably haven&#8217;t been clear enough, but luckily various commenters have picked up on this: I&#8217;m not advocating removing assertions and replacing them with nothing! In general, I think assertions should be replaced with a stronger check that also runs (or can run) in a release build.</em></p>
<p><strong>1. Pointless Guard Checking</strong></p>
<p>Unfortunately in my coding travels I see quite a bit of code like this:</p>
<pre>void Foo(Bar bar)
{
  Debug.Assert(bar != null);

  bar.DoSomething();
}</pre>
<p>What&#8217;s the point? If bar is null, then using it will throw an exception anyway. Why add unnecessary lines of code that make reading harder?</p>
<p><strong>2. Bad Argument Checking</strong></p>
<p>But, you&#8217;re thinking, what if the usage is separated from the assignment?</p>
<pre>class Foo
{
  public Foo(Bar bar)
  {
    Debug.Assert(bar != null);

    _bar = bar;
  }

  public void Method()
  {
    _bar.DoSomething();
  }

  private Bar _bar;
}</pre>
<p>True, you want to catch the error as it happens, not later on in the method. But shouldn&#8217;t you be throwing an ArgumentNullException instead?</p>
<p><strong>3. Difficult Detective Work</strong></p>
<p>So now you&#8217;re telling me that you&#8217;re not writing component code, and the only client of this class will be the application it&#8217;s embedded in. Why not save some effort and skimp on the checking code, and make it debug-only?</p>
<p>Fine idea&#8230; until you get a crash report from one of your users, and the stacktrace points to a NullReferenceException in Method(). Now you have to figure out where the null value got passed to the constructor&#8230; a potentially much more difficult task.</p>
<p><strong>4. Differences Between Debug and Release</strong></p>
<p>If you&#8217;re like me, you generally run the applications in debug. Your customers however, run in release. Why make the differences between these two versions any bigger? Even if you don&#8217;t intend your debug statements to change program state, it&#8217;s all too easy to accidentally do so:</p>
<ul>
<li>Running lazy-initializers or singleton constructors;</li>
<li>Loading data from the database via an ORM;</li>
<li>Moving data in or out of a cache;</li>
<li>Running static constructors.</li>
</ul>
<p><strong>5. Too-Shy Sanity-Checking</strong></p>
<p>Sometimes, despite the above warning, you really do have sanity-checking code that you&#8217;d like to run in a development or test environment to catch regressions, but which is too slow to give to general users. (I read somewhere that Excel has two computation engines: a simple, slow, reference one, and a fast, parallel, release one. Testers can run the two in parallel, and any differences are automatically flagged as errors).</p>
<p>So you might be tempted to do something like:</p>
<pre>Debug.Assert( SlowlyAndCarefullyVerifyInternalState() );</pre>
<p>The problem I have with this is that the debug/release division is way too blunt.</p>
<ul>
<li>Suppose a tester wants to test a release build, but also perform the sanity-checking?</li>
<li>Suppose a customer finds a bug in a complex calculation, and you want them to run the checks?</li>
<li>Suppose a developer wants to debug performance issues in the non-checked code?</li>
</ul>
<p>I would suggest you move the conditionals for code like this to a (possibly hidden) configuration setting. Someone wants to run in slow-and-safe mode? No problem, just tell them the registry setting (or whatever). By all means, change the splash screen or title bar or whatever so it says &#8220;test mode&#8221;.</p>
<p>The advantages of this method are:</p>
<ul>
<li>Anyone can turn it on and off;</li>
<li>Sanity-checking can be controlled at a much finer granularity than all-on / all-off.</li>
</ul>
<p><strong>6. Is It Recoverable, Or Not?</strong></p>
<p>The final argument against debug assertions concerns just exactly what an assertion means.</p>
<p>To my mind, an assertion is different to a simple flow-control test (&#8220;did the user enter a valid number?&#8221;), which is something the program can (should) handle. By definition, an assertion is checking for a disallowed state. An assertion doesn&#8217;t check for incorrect data; it checks for an incorrect program. Continuing after an assertion leads to undefined behaviour.</p>
<p>So how can you continue? More to the point, why should a user even be allowed to continue? If the state really is unrecoverable, then fail. Fail fast, log the error, and bail (possibly trying to allow the user to save work, or whatever). Having a release-build application continue after what would have been an assertion is just plain wrong.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2009/06/10/debug-assert-considered-pointless/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Learning? Me? But I&#8217;m An Expert</title>
		<link>http://www.hackification.com/2009/05/05/learning-me-but-im-an-expert/</link>
		<comments>http://www.hackification.com/2009/05/05/learning-me-but-im-an-expert/#comments</comments>
		<pubDate>Tue, 05 May 2009 11:56:15 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[quotes]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=167</guid>
		<description><![CDATA[You&#8217;ve been a coder for a few years now, maybe even decades. You&#8217;ve got a successful job, making enough money. You know the &#8220;respectable&#8221; technologies that the recruiters look for: C++, C#, Java, whatever. There&#8217;s no need to learn anything new. Stay in your comfort zone. Take it from these guys:

&#8220;I think there’s a world [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-176" style="margin-left: 8px; margin-right: 8px;" title="Dinosaur" src="http://www.hackification.com/wp-content/uploads/2009/05/dinosaur.png" alt="Dinosaur" width="124" height="100" />You&#8217;ve been a coder for a few years now, maybe even decades. You&#8217;ve got a successful job, making enough money. You know the &#8220;respectable&#8221; technologies that the recruiters look for: C++, C#, Java, whatever. There&#8217;s no need to learn anything new. Stay in your comfort zone. Take it from these guys:</p>
<p><span id="more-167"></span></p>
<blockquote><p><strong>&#8220;I think there’s a world market for about 5 computers.&#8221;</strong><br />
<em></em></p>
<p><em>- Thomas J. Watson, Chairman of the Board, IBM, circa 1948</em></p></blockquote>
<blockquote><p><strong>&#8220;It would appear that we have reached the limits of what it is possible to achieve with computer technology, although one should be careful with such statements, as they tend to sound pretty silly in 5 years.&#8221;</strong><br />
<em></em></p>
<p><em>- John Von Neumann, circa 1949</em></p></blockquote>
<blockquote><p><strong>&#8220;But what is it good for?&#8221;</strong><br />
<em></em></p>
<p><em>- Engineer at the Advanced Computing Systems Division of IBM, commenting on the microchip, 1968</em></p></blockquote>
<blockquote><p><strong>&#8220;There is no reason for any individual to have a computer in his home.&#8221;</strong><br />
<em></em></p>
<p><em>- Ken Olson, President, Digital Equipment Corporation, 1977</em></p></blockquote>
<p>Wise words indeed.</p>
<p>You need to learn when you know you don&#8217;t know enough, sure. It&#8217;s easy to pick up a book when you&#8217;re feeling clueless. The more dangerous time is when you think you do know enough. Coding (and computer science) is like the <a href="http://en.wikipedia.org/wiki/Red_Queen%27s_race" target="_blank">Red Queen&#8217;s Race</a>: you need to run as fast as you can just to stay still.</p>
<ul>
<li>When was the last time you bought or borrowed a technical book?</li>
<li>When was the last time you bought or borrowed a technical book, and then <em>actually </em><em>read it</em>?</li>
<li>When was the last time you bought or borrowed a technical book, and read it, <em>where it was of no immediate use to your job</em>?</li>
</ul>
<p><strong>Leave your comfort zone. Admit your ignorance. Learn something new. Learn something useless. Because next year, you might be kicking yourself for calling it useless. Don&#8217;t tell me that what you know now is all you&#8217;ll ever need to know. Don&#8217;t get quoted in next year&#8217;s list.</strong></p>
<p><em>If you liked the quotes above, you might also be interested in &#8220;<a title="Permanent Link: A Double Handful of Programming Quotes" rel="bookmark" href="../2008/12/23/a-double-handful-of-programming-quotes/">A Double Handful of Programming Quotes</a>&#8220;.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2009/05/05/learning-me-but-im-an-expert/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Forcing The Browser To Cache Dynamic Content In ASP.NET</title>
		<link>http://www.hackification.com/2009/05/01/forcing-the-browser-to-cache-dynamic-content-in-aspnet/</link>
		<comments>http://www.hackification.com/2009/05/01/forcing-the-browser-to-cache-dynamic-content-in-aspnet/#comments</comments>
		<pubDate>Fri, 01 May 2009 09:14:41 +0000</pubDate>
		<dc:creator>stusmith</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[caching]]></category>

		<guid isPermaLink="false">http://www.hackification.com/?p=143</guid>
		<description><![CDATA[Usually, you don&#8217;t want the browser doing any kind of caching on dynamic content served from a generic handler (.ASHX) in ASP.NET &#8211; afterall, the content is usually changing (dynamic). Sometimes however, it&#8217;s handy to use a handler to serve content that effectively never changes. Here&#8217;s how.
One common example (that we make use of heavily [...]]]></description>
			<content:encoded><![CDATA[<p>Usually, you don&#8217;t want the browser doing any kind of caching on dynamic content served from a generic handler (.ASHX) in ASP.NET &#8211; afterall, the content is usually changing (dynamic). Sometimes however, it&#8217;s handy to use a handler to serve content that effectively never changes. Here&#8217;s how.</p>
<p><span id="more-143"></span>One common example (that we make use of heavily in <a title="EasyAs123Web.com" href="http://www.easyas123web.com" target="_blank">EasyAs123Web.com</a>) is using a handler to serve and generate images on-the-fly. Our user images are stored in the database, and are immutable &#8211; they never change. Hence we&#8217;d like the client browser to cache the image returned.</p>
<p><strong>Example Handler</strong></p>
<p>Let&#8217;s start with the shell of a generic handler, MyHandler.ashx.cs:</p>
<pre>public class MyHandler : IHttpHandler
{
  public void ProcessRequest( HttpContext context )
  {
    ...
  }

  public bool IsReusable
  {
    get
    {
      return true;
    }
  }
}</pre>
<p>Further code will go where I&#8217;ve marked with ellipses.</p>
<p><strong>Reponse Headers</strong></p>
<p>For some reason, ASP.NET automatically adds headers that stop the browser from caching the content, and you can&#8217;t just override them. Instead, you&#8217;ll need to clear them all out first:</p>
<pre>context.Response.ClearHeaders();</pre>
<p>Next we want to mark the content as fully cacheable, and expiring at some date in the future:</p>
<pre>context.Response.Cache.SetValidUntilExpires( true );
context.Response.Cache.SetCacheability( HttpCacheability.Public );
context.Response.Cache.SetExpires( DateTime.Now.AddMonths( 1 ) );
context.Response.Cache.SetLastModified( DateTime.Now.AddMonths( -1 ) );</pre>
<p>(I&#8217;ve marked the content as expiring in a month, but you could easily add a year or ten years or whatever).</p>
<p>If you are able to calculate some form of hash for your content (which you should be able to do pretty easily), you can add an <a href="http://en.wikipedia.org/wiki/HTTP_ETag" target="_blank">ETag</a>:</p>
<pre>Guid hash = ...;

context.Response.Cache.SetETag( "\"" + hash.ToString().Replace( "-", "" ) + "\"" );</pre>
<p>Finally, there&#8217;s one more trick which is incredibly useful for allowing browsers to avoid re-downloading the content.</p>
<p>Browsers may include the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25" target="_blank">&#8220;If-Modified-Since&#8221; request header</a>. If you ignore this header, no problems occur: you just send the content as usual. However, you can use it to inform the browser that your content hasn&#8217;t changed since the last time it was requested.</p>
<p>If your content really hasn&#8217;t changed, instead of sending a &#8220;200 OK&#8221; response with all the content, you can send back a &#8220;304 Not Modified&#8221; without any content whatsoever:</p>
<pre>var textIfModifiedSince = context.Request.Headers["If-Modified-Since"];

if( !string.IsNullOrEmpty( textIfModifiedSince ) )
{
  context.Response.Status = "304 Not Modified";
  context.Response.End();

  return;
}</pre>
<p>So instead of sending back a potentially large piece of content, you can send back just the tiny response headers.</p>
<p>You can do a similar trick with <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26" target="_blank">&#8220;If-None-Match&#8221;</a> &#8211; I&#8217;ll leave that as an exercise.</p>
<p><strong>Debugging</strong></p>
<p>Making these changes is all very well, but can you be sure that your changes are actually having the desired effects?</p>
<p>There are two great tools you can use to actually view the requests sent by the browser, and the response sent from your web-app:</p>
<ul>
<li>For debugging with Firefox: <a href="https://addons.mozilla.org/en-US/firefox/addon/3829" target="_blank">Live HTTP Headers</a>.</li>
<li>For Internet Explorer: <a href="http://www.fiddler2.com/fiddler2/" target="_blank">Fiddler 2</a>.</li>
</ul>
<p>If you care about the speed and bandwidth usage of your ASP.NET application, I&#8217;d say that these two are pretty much indispensable. You&#8217;ll want to test with both: different browsers make subtly different requests, and interpret the responses differently.</p>
<p>You might also want to use <a href="https://addons.mozilla.org/en-US/firefox/addon/5369" target="_blank">YSlow</a> for Firebug: this has some nice graphical displays of page assets.</p>
<p><strong>Example &#8211; Content Not In Cache</strong></p>
<p>Request and response, some lines omitted for clarity.<strong><br />
</strong></p>
<pre>GET /!!/_Serving/StaticFile/Style/Pro/Images/HomeCreate.jpg HTTP/1.1
Host: www.easyas123web.com</pre>
<pre>HTTP/1.x 200 OK
Cache-Control: public
Content-Type: image/jpeg
Expires: Mon, 01 Jun 2009 08:58:36 GMT
Last-Modified: Wed, 01 Apr 2009 08:58:36 GMT
Etag: "45403f772717d1c63c0b8774e4a124b7"
Content-Length: 20696
... 20K of content here ...</pre>
<p><strong>Example &#8211; Content In Cache</strong></p>
<p>Request and response, some lines omitted for clarity.<strong><br />
</strong></p>
<pre>GET /!!/_Serving/StaticFile/Style/Pro/Images/HomeCreate.jpg HTTP/1.1
Host: www.easyas123web.com
If-Modified-Since: Wed, 01 Apr 2009 08:58:36 GMT</pre>
<pre>HTTP/1.x 304 Not Modified
Cache-Control: public
Expires: Mon, 01 Jun 2009 09:03:51 GMT
Last-Modified: Wed, 01 Apr 2009 09:03:51 GMT
Etag: "45403f772717d1c63c0b8774e4a124b7"</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.hackification.com/2009/05/01/forcing-the-browser-to-cache-dynamic-content-in-aspnet/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
