<?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"?><!-- generator="wordpress/2.2.3" --><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/" version="2.0">

<channel>
	<title>James Crisp » Technical</title>
	<link>http://jamescrisp.org</link>
	<description>C#, JRuby, Ruby on Rails, .NET, book reviews, film reviews, mind hacks, Wing Chun and the occasional personal bit.</description>
	<pubDate>Tue, 22 Dec 2009 10:42:29 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2.3</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/JamesCrispTechnical" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="jamescrisptechnical" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>HTML to PDF Conversion Plugin For Rails (A fork of wicked pdf)</title>
		<link>http://jamescrisp.org/2009/11/12/html-to-pdf-conversion-plugin-for-rails-a-fork-of-wicked-pdf/</link>
		<comments>http://jamescrisp.org/2009/11/12/html-to-pdf-conversion-plugin-for-rails-a-fork-of-wicked-pdf/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 04:47:07 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/11/12/html-to-pdf-conversion-plugin-for-rails-a-fork-of-wicked-pdf/</guid>
		<description><![CDATA[Once a business web application reaches a certain size, the need often arises to generate PDFs from HTML/CSS. 
Up until recently, the story around this for a MRI Rails application was not good. You could either use tools like Prawn, which require a description of the layout in a specific DSL, or pay for a [...]]]></description>
			<content:encoded><![CDATA[<p>Once a business web application reaches a certain size, the need often arises to generate PDFs from HTML/CSS. </p>
<p>Up until recently, the story around this for a MRI Rails application was not good. You could either use tools like <a href="http://prawn.majesticseacreature.com/">Prawn</a>, which require a description of the layout in a specific DSL, or pay for a tool like <a href="http://www.princexml.com/">Prince XML</a> which can convert from HTML, but which costs quite a bit. Those using <a href="http://jruby.org/">JRuby</a> were in a stronger position as they could use the Java PDF library called <a href="https://xhtmlrenderer.dev.java.net/">Flying Saucer</a>.</p>
<p>The good news is that PDF generation for MRI Ruby is now easy and free, thanks to <a href="http://webkit.org/">webkit</a>, the open source webkit wrapper called <a href="http://code.google.com/p/wkhtmltopdf/">wkhtmltopdf</a> and <a href="http://mileszs.com/blog/2009/06/17/wicked-pdf-plugin.html">mileszs's wickedpdf plugin</a>. I was really excited to come across this plugin and started to use it right away. However, it had a couple of issues:</p>
<ul>
<li>Temp file handling caused errors when two PDFs were being generated within the same second (eg, 2 requests at almost the same time)</li>
<li>Problems generating PDF were not reported</li>
</ul>
<p><a href="http://github.com/galdomedia/wicked_pdf">Galdomedia</a> forked the code and updated it to use standard Ruby temp files. This was great for ruby 1.7, but not good for Ruby 1.6 which does not allow you to set the extension on temp files (wkhtmltopdf relies on having a .html extension). </p>
<p>As my production servers run Ruby 1.6, I needed a different approach. <a href="http://github.com/jcrisp/wicked_pdf">My fork</a> uses streams rather than temporary files, and adds some basic error handling and basic integration tests.</p>
<p>To install in a rails app:</p>
<pre>
script/plugin install git://github.com/jcrisp/wicked_pdf.git
</pre>
<p>Or <a href="http://github.com/jcrisp/wicked_pdf">clone the code from GitHub</a>.
</pre>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/11/12/html-to-pdf-conversion-plugin-for-rails-a-fork-of-wicked-pdf/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Presentation Zen by Garr Reynolds</title>
		<link>http://jamescrisp.org/2009/11/09/presentation-zen-by-garr-reynolds/</link>
		<comments>http://jamescrisp.org/2009/11/09/presentation-zen-by-garr-reynolds/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 04:25:23 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Talks]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/11/09/presentation-zen-by-garr-reynolds/</guid>
		<description><![CDATA[After being impressed by Garr Reynolds speaking in Sydney a year or so ago, I've been keen to check out his Presentation Zen book. It is an enlightening read, especially if you have never studied art or graphics design. The book is a little over 200 pages long, with many illustrations and a impressive, clean [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2009/11/presentationzen.jpg' title='presentationzen.jpg'><img src='http://jamescrisp.org/wordpress/wp-content/uploads/2009/11/presentationzen.thumbnail.jpg' alt='presentationzen.jpg' style="float: left; margin-right: 5px;"/></a>After being impressed by <a href="http://www.presentationzen.com/">Garr Reynolds</a> speaking in Sydney a year or so ago, I've been keen to check out his <a href="http://www.amazon.com/Presentation-Zen-Simple-Design-Delivery/dp/0321525655/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1257723978&#038;sr=8-1">Presentation Zen</a> book. It is an enlightening read, especially if you have never studied art or graphics design. The book is a little over 200 pages long, with many illustrations and a impressive, clean layout (no surprise there!).</p>
<p>Near the start of the book, Garr talks about creativity requiring an open mind (child like) and a willingness to be wrong, and to experiment. He recommends exercising restraint, and focusing on simplicity, clarity and brevity. He starts presentations brainstorming using pen and paper, whiteboards or post-its rather than in front of the computer (personally I often use story cards as you can jot slide outlines on them, group, and shift the order around). He recommends grouping the ideas, and identifying the core message and sticking with that message throughout the whole presentation.</p>
<p>Garr highlights the importance of taking the time to slow down and really think about what to put in the presentation. He suggests that you keep two important questions in mind: "What's your point?" (what one thing do you want the audience to remember), and "Why does it matter?" (put yourself in the audiences' shoes). If bits of your content don't aid in answering these questions, "when in doubt, cut it out"! Garr also suggests an "Elevator test" - can you make your pitch in 30-45 seconds? A structure that works well is starting with an introduction which explains the issue (the pain) and the core message. Then something like 3 parts that support your assertions or solve the pain (sounds a bit like <a href="http://www.amazon.com/Solution-Selling-Creating-Difficult-Markets/dp/0786303158/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1257727513&#038;sr=8-1">Bosworth's Solution Selling</a>).</p>
<p>"Amplification through simplification" is central to Garr's design approach. He advocates lots of empty space to highlight just one or a few important elements on a slide. "Simplicity can be obtained through the careful reduction of the non-essential" and decreasing the signal vs noise ratio of the slides. Garr is a big fan of using images on slides with just a few words. The aim is to make slides which have strong, memorable impact, and enhance the presenter's spoken words. He also highlights the importance of having the audience know where to look. Eg, simplicity plus images leading the eye to the right spot (eg, people in images on the slide look towards the words on the slide). Garr is a big fan of using quotes to support his points.</p>
<p>Garr suggests a mix of symmetrical and asymmetrical slides. Symmetrical are more formal and static, where as asymmetrical slides are often more dynamic and interesting and activate empty space. He also suggests using a grid, such as the <a href="http://en.wikipedia.org/wiki/Rule_of_thirds">rule of thirds</a> (2 horizontal and 2 vertical lines providing a grid of 9 equally sized boxes), with the main subject placed on one of the crossing points of the lines. Contrast (using colour, shape, space, etc) can be used to make an element stand out and helps the viewer "get" the point of the design quickly. Repetition can be used (eg, text on each slide in an image of a post-it) to provide a professional and unified look. Use proximity to group related objects.</p>
<p>Although Garr doesn't talk about it explicity, his sample slides tend to make use of clever typography. Often lower case text, with most important part in a bigger font. A mix of colours and sizes and styles and sometimes rotations to add interest to the slides. Generally sans-serif fonts.</p>
<p>On presenting itself, Garr says you should be completely present - enthusiastic and completely focused on presentation that you are giving, lost in the moment. Nothing else. Although you may make mistakes, don't dwell on them. Practice like mad to become confident and appear easy and natural for the presentation. However, remain flexible, aware and open to possibilities as they arise (being "in the moment").</p>
<p>Near the end of the book, Garr says: "It's not about us [the presenter], it's about them. And about the message.". He also suggests that shorter is better, leave the audience wanting more, not overloaded (as per Japanese proverb "eat until 80% full"). On delivery, Garr suggests standing front and centre, leaving the lights on and advancing slides with a remote.</p>
<p>Garr's points are much more clearly illustrated using images in the book. I would recommend Presentation Zen to anyone who is interested in making more visually inspiring and interesting presentations. </p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/11/09/presentation-zen-by-garr-reynolds/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Percent Number in Apache Rewrite Rules (mod_rewrite)</title>
		<link>http://jamescrisp.org/2009/11/05/percent-number-in-apache-rewrite-rules-mod_rewrite/</link>
		<comments>http://jamescrisp.org/2009/11/05/percent-number-in-apache-rewrite-rules-mod_rewrite/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 01:16:49 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/11/05/percent-number-in-apache-rewrite-rules-mod_rewrite/</guid>
		<description><![CDATA[What do the %1 %2 in a Rewrite rule mean? The Apache guide does not help, nor does any other documentation I found. I came across the %1, %2 etc in some complex and arcane rules. Google ignores percent signs, which makes it hard to get an easy answer.
We'll use the rules from my last [...]]]></description>
			<content:encoded><![CDATA[<p>What do the %1 %2 in a Rewrite rule mean? The Apache guide does not help, nor does any other documentation I found. I came across the %1, %2 etc in some complex and arcane rules. Google ignores percent signs, which makes it hard to get an easy answer.</p>
<p>We'll use the rules from my last post as an example.</p>
<p><code>RewriteCond %{HTTP_HOST} !^www\. [NC]<br />
RewriteCond %{HTTP_HOST} ^<strong>([a-z.]+)</strong>$ [NC]<br />
RewriteRule ^/(.*)$ http://www.<strong>%1</strong>/$1 [R=301,L]</code></p>
<p>The %1 refers to the capture group in a previous RewriteCond. This differentiates it from the $1 which refers to a capture group in the current RewriteRule.</p>
<p>Hopefully I have littered this post with enough keywords that future googlers will find the answer to the %1 %2 in ReWrite rules more easily <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/11/05/percent-number-in-apache-rewrite-rules-mod_rewrite/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Adding WWW to domains, and Apache Rewrite Rules (mod_rewrite)</title>
		<link>http://jamescrisp.org/2009/11/05/adding-www-subdomain-with-apache-rewrite-rules-mod_rewrite/</link>
		<comments>http://jamescrisp.org/2009/11/05/adding-www-subdomain-with-apache-rewrite-rules-mod_rewrite/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 00:54:45 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Design / Architecture]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/11/05/adding-the-www-subdomain-with-apache-rewrite-rules-mod_rewrite/</guid>
		<description><![CDATA[Browse to http://google.com. Then look at the address bar. You're not really at http://google.com. You've been redirected to http://www.google.com. Try the same on w3c, Facebook, Sydney Morning Herald etc.
Why WWW?
Why do all these sites redirect you to a www form? Well, the main reason is because it is advantageous to have a canonical URL, and, [...]]]></description>
			<content:encoded><![CDATA[<p>Browse to <a rel="external nofollow" href="http://google.com">http://google.com</a>. Then look at the address bar. You're not really at <a rel="external nofollow" href="http://google.com">http://google.com</a>. You've been redirected to <a rel="external nofollow" href="http://www.google.com">http://<strong>www.</strong>google.com</a>. Try the same on w3c, Facebook, Sydney Morning Herald etc.</p>
<p><strong>Why WWW?</strong><br />
Why do all these sites redirect you to a www form? Well, the main reason is because it is advantageous to have a canonical URL, and, if your have to choose one URL, you might as well go with what people seem to expect, which is to include a 'www'.</p>
<p>What's so great about having one canonical URL?</p>
<ul>
<li>Cookies: if your users can access the site at www.domain.com and domain.com, you can end up with some horrible cookie and session problems depending on the browser and web framework (behaviour is different between Firefox and IE). Stay tuned for another post with more details on this.</li>
<li>Certificates for HTTPS: certificates are usually for a single domain. If your site is available with and without 'www', your site will need a certificate for each or a multi-domain certificate (ie, more money and config).</li>
<li>Caching: if you have two URLS, any HTTP caching will only be half as effective</li>
<li>SEO: your page rank may be split between links to both possible URLs (though Google Webmaster tools seems to let you combine it)</li>
</ul>
<p><strong>How?</strong><br />
Right so, now you're probably just hoping there is an easy way to implement this forced 'www' business! Well the good news is that it's quite easy if you're using Apache with mod_rewrite. I googled around to try and find some good rules, but the ones I found were tied to a single hard coded domain (no good for me where I have multiple domains pointing to the same server for different countries). See below for what I came up with. It seems to work quite well. You can put it in your virtual host configuration file or even .htaccess file.</p>
<p><code>RewriteEngine on<br />
RewriteCond %{HTTP_HOST} !^www\. [NC]<br />
RewriteCond %{HTTP_HOST} ^([a-z.]+)$ [NC]<br />
RewriteRule ^/(.*)$ http://www.%1/$1 [R=301,L]</code></p>
<p>Line 1: Are you coming to the site without www. at the start of the host? [NC] means ignore case.</p>
<p>Line 2: Does your domain comprise of letters and dots (this means that going to the IP address will not fire the rewrite rule). Grab the domain in a capture group.</p>
<p>Line 3: Rewrite the URL with a www at the front, and keep the hostname from the previous condition (%1) and the path after the domain ($1). Use a status code 301, to tell the client that this is a permanent redirect.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/11/05/adding-www-subdomain-with-apache-rewrite-rules-mod_rewrite/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Po: Beyond Yes and No by Edward de Bono (Book Review)</title>
		<link>http://jamescrisp.org/2009/10/23/po-beyond-yes-and-no-by-edward-de-bono-book-review/</link>
		<comments>http://jamescrisp.org/2009/10/23/po-beyond-yes-and-no-by-edward-de-bono-book-review/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 06:38:19 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Soft Skills and Mind Hacks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/10/23/po-beyond-yes-and-no-by-edward-de-bono-book-review/</guid>
		<description><![CDATA[A few months back, I came across Edward de Bono's book on Po at a local post office second hand book sale. I decided to risk 50c and buy this out of print, 1972 edition book on creativity and lateral thinking. It was worth every cent  
Until you get a fair way into the [...]]]></description>
			<content:encoded><![CDATA[<p>A few months back, I came across Edward de Bono's book on Po at a local post office second hand book sale. I decided to risk 50c and buy this out of print, 1972 edition book on creativity and lateral thinking. It was worth every cent <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Until you get a fair way into the book, it's quite hard to work out what it is about. It is also quite wordy, and oddly organised. However, after reading it for a bit, I found it had some interesting ideas.</p>
<p>De Bono is not a big fan of the yes/no system or argument. He proposes that yes/no mindset that people usually use means that somebody has to be right and somebody wrong. With this mindset, an old theory cannot be replaced by a better one until it can be proven wrong by argument. For subjective subjects, this is not often possible. He proposes that when people have a "right" answer, they are happy and stop looking for a better answer, curbing creativity. Similarly, a "wrong" answer stops that train of thought - and perhaps if it had continued, then a good answer might have been found with ideas triggered from the "wrong" answer.</p>
<p>De Bono sets up PO as an alternative to the Yes / No system and  talks about it as a way to break down established patterns and introduce discontinuity in thinking to come up with new ideas. He sees it as an alternative to the "clash" of argument and the "arrogance of logic" in the "closed and highly artificial world" of education, that in later life leads to a "need to be right". He says that this "need to be right" then leads to people "defending not the idea, but your self-esteem" and having high resistance to new ideas and change.</p>
<p>De Bono disputes a common idea that by choosing the best answer in a series of questions or steps leads to the optimal solution at the end. He shows several examples where choosing the most optimal answer for each step leads to a solution which is not optimal. </p>
<p>Arguably the most interesting part of the book describes a number of tools for lateral thinking.</p>
<p><b>PO-1: Intermediate Impossible</b><br />
Rather than immediately rejecting an impossible idea, look at it longer for good points. Reconsider your framework of judgment and concept package - maybe idea is right if you consider the situation in a different way. The idea can be a stepping stone to a better idea. When other people come up with a "wrong idea" listen longer and see where it can take you. This approach can be used as a tool - turn the "idea upside down, inside out, back to front" and "say the most unlikely and outrageous thing you can about the situation - and see where it gets you". </p>
<p><b>PO-2: Random Juxtaposition</b><br />
"When you have exhausted the different ways of looking at the problem from within, you bring in" a random word "in order to generate a fresh approach" through juxtaposition and connecting the words. The random word can be from opening a dictionary at random or from a list of "idea provoking" words.</p>
<p><b>PO-3: Change without rejection, by-passing old concepts to generate alternatives</b><br />
"That idea is fine, but let us put it on one side and find a new way of looking at things", "this is one way of looking at things and it is perfectly valid but it does not exclude other ways, so let us try to find some" or "I wonder if there are other ways of looking at this". "Why do we have to look at things that way", lets reconsider our starting point and understanding.</p>
<p>The last part I want to mention is the discussion of retardant doubt. De Bono suggests that with a Yes/No, boolean mindset, you require certainty of being right before acting. If you don't have this certainty, your doubt holds you back. You may even create false certainty so that you can act (leading to problems later since you'll then defend this false certainty). However, in the Po system, there is no certainty. The premise is only that the "current way of looking at things is the best one at the moment, but may need changing very soon". This means you can act without certainty - your action might not be right in the absolute sense, but you are ready to "change it as soon as circumstances demand". With the Po approach you explore a wide range of alternatives, choose the most effective idea for now, but be ready to change it for something even better.</p>
<p>Overall, I enjoyed the book (though skimmed some more repetitive bits) and plan to try out some of the lateral thinking tools. If you want to get the book, a second hand bookshop is probably a good option. It is <a href="http://www.amazon.com/PO-BEYOND-YES-NO-BONO/dp/B000S4F1DE/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1256279748&#038;sr=8-1">quite expensive on Amazon</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/10/23/po-beyond-yes-and-no-by-edward-de-bono-book-review/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Slides &amp; Code: Securing your MVC site against Code Injection and X-Site Scripting</title>
		<link>http://jamescrisp.org/2009/08/26/slides-code-securing-your-mvc-site-against-code-injection-and-x-site-scripting/</link>
		<comments>http://jamescrisp.org/2009/08/26/slides-code-securing-your-mvc-site-against-code-injection-and-x-site-scripting/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 05:34:07 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[ALT.NET]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/08/26/slides-code-securing-your-mvc-site-against-code-injection-and-x-site-scripting/</guid>
		<description><![CDATA[Here are the slides and code from yesterday's talk at Sydney ALT.NET.
See Steve Sanderson's post for the code/binary for subclassed aspx compiler and more information about the automatic encoding approach we covered in the talk.
]]></description>
			<content:encoded><![CDATA[<p>Here are the <a href='http://jamescrisp.org/wordpress/wp-content/uploads/2009/08/securingmvcagainstcodeinjection.zip' title='Slides and code for securing your asp.net mvc site against x-site scripting and code injection'>slides and code</a> from <a href="http://jamescrisp.org/2009/08/18/talk-securing-your-mvc-site-against-code-injection-and-x-site-scripting/">yesterday's talk</a> at <a href="http://sydney.ozalt.net">Sydney ALT.NET</a>.</p>
<p>See <a href="http://blog.codeville.net/2007/12/19/aspnet-mvc-prevent-xss-with-automatic-html-encoding/">Steve Sanderson's post</a> for the code/binary for subclassed aspx compiler and more information about the automatic encoding approach we covered in the talk.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/08/26/slides-code-securing-your-mvc-site-against-code-injection-and-x-site-scripting/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Windows / .NET Dev Tools</title>
		<link>http://jamescrisp.org/2009/08/18/windows-net-dev-tools/</link>
		<comments>http://jamescrisp.org/2009/08/18/windows-net-dev-tools/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 01:42:44 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Windows]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/08/18/windows-net-dev-tools/</guid>
		<description><![CDATA[Recently I visited a .NET dev team to take a look at design, code and processes with a view to making recommendations to improve delivery speed. One of the more minor, but easily generalisable areas is around tooling. I often find that the little extra tools you pick up can make your work significantly more [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I visited a .NET dev team to take a look at design, code and processes with a view to making recommendations to improve delivery speed. One of the more minor, but easily generalisable areas is around tooling. I often find that the little extra tools you pick up can make your work significantly more efficient. Here are a few free ones I use:</p>
<p><b><a href="http://kdiff3.sourceforge.net/">KDiff3</a></b><br />
A brilliant merge tool that plugs nicely into TFS or SVN. SVN integration is automatic from the Kdiff3 installer. TFS integration is manual, but <a href="http://blogs.msdn.com/jmanning/articles/535573.aspx">quite easy</a>.</p>
<p><b><a href="http://sourceforge.net/projects/console/">Console2</a></b><br />
A tabbed console which works well with classic windows shell and powershell. Good support for resizing, copy paste, etc.</p>
<p><b><a href="http://www.red-gate.com/products/reflector/">.NET Reflector</a></b><br />
.NET decompiler for those dlls that don't have source. There is also a great plugin that lets you decompile entire assemblies to files on disk.</p>
<p><b><a href="http://www.fiddler2.com/fiddler2/">Fiddler</a></b><br />
When you're debugging SOAP or RESTful web services, Fiddler is great. It lets you see the messages sent / received and even change and impersonate them.</p>
<p><b><a href="http://www.albahari.com/queryexpress.aspx">QueryExpress</a></b><br />
If you've got SQLExpress or just no tools installed, QueryExpress is a tiny (~100K) and quick query analyser style application for all breeds of MS SQLServer. Download in a few seconds, and be running queries before a minute is up.</p>
<p><b><a href="http://ccollomb.free.fr/unlocker/">Unlocker</a></b><br />
Don't you hate it when Windows gets its locks in a mess and you can't delete/rename files? Unlocker will automatically pop up, show you which applications are holding file locks and let you release the locks.</p>
<p><b><a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">Process Explorer</a></b><br />
A more powerful and accurate Task Manager application which allows you to see file locks and many other types of information.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/08/18/windows-net-dev-tools/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Talk: Securing your MVC site against Code Injection and X-Site Scripting</title>
		<link>http://jamescrisp.org/2009/08/18/talk-securing-your-mvc-site-against-code-injection-and-x-site-scripting/</link>
		<comments>http://jamescrisp.org/2009/08/18/talk-securing-your-mvc-site-against-code-injection-and-x-site-scripting/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 01:08:52 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[ALT.NET]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/08/18/talk-securing-your-mvc-site-against-code-injection-and-x-site-scripting/</guid>
		<description><![CDATA[I'll be giving a lightning talk on securing your ASP.NET MVC site against code injection and x-site scripting next Tuesday 25 August at the Sydney ALT.NET group. I'll be demonstrating potential pitfalls and dangers of arbitary code injection, and how you can protect against it, elegantly. We've got 6 interesting talks lined up for the [...]]]></description>
			<content:encoded><![CDATA[<p>I'll be giving a lightning talk on securing your ASP.NET MVC site against code injection and x-site scripting next Tuesday 25 August at the <a href="http://sydney.ozalt.net">Sydney ALT.NET group</a>. I'll be demonstrating potential pitfalls and dangers of arbitary code injection, and how you can protect against it, elegantly. We've got <a href="http://sydney.ozalt.net/2009/08/august-lightning-talks-subjects.html">6 interesting talks</a> lined up for the night. See you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/08/18/talk-securing-your-mvc-site-against-code-injection-and-x-site-scripting/feed/</wfw:commentRss>
		</item>
		<item>
		<title>“Ruby for Rails” by David Black</title>
		<link>http://jamescrisp.org/2009/08/10/ruby-for-rails-by-david-black/</link>
		<comments>http://jamescrisp.org/2009/08/10/ruby-for-rails-by-david-black/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 07:46:14 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/08/10/ruby-for-rails-by-david-black/</guid>
		<description><![CDATA[Ruby for Rails by David Black is a fun read that takes concentration but repays it with little epiphanies that explain syntax and language features that you had previously taken for granted.
The book aims to "help Rails developers achieve Ruby mastery". The coverage of Ruby features is not complete and there are some concepts missed [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/1932394699?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=1932394699"><img src='http://jamescrisp.org/wordpress/wp-content/uploads/2009/08/ruby_for_rails.jpg' alt='Ruby For Rails' style="margin: 5px 10px 5px 0pt; float: left;" /></a><a href="http://www.amazon.com/gp/product/1932394699?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=1932394699">Ruby for Rails</a> by David Black is a fun read that takes concentration but repays it with little epiphanies that explain syntax and language features that you had previously taken for granted.</p>
<p>The book aims to "help Rails developers achieve Ruby mastery". The coverage of Ruby features is not complete and there are some concepts missed that I would have liked to have read more about (eg, how do instance variables work under the hood?). There are also a number of introductory chapters on Ruby and Rails and some chapters devoted to a sample Rails project (R4RMusic) which I flicked through but didn't add much value for me (they are also a little dated). By far, the most interesting parts of the book for me were on the Ruby type system, 'self' in various situations and how method look up works with modules and inheritance.</p>
<p>An area of Ruby that I had not previously explored was adding singleton methods to instances (like what you can do in Javascript). Eg,</p>
<pre>
o = Object.new
def o.say_hi
  p "hi"
end

>> o.say_hi
"hi"
</pre>
<p>or alternatively</p>
<pre>
o = Object.new
class << o
  def say_hi
    p "hi"
  end
end
</pre>
<p>Now, the interesting thing is that this is the basis for the whole class system in Ruby!</p>
<p>Classes are just a special type of object, and when you add class methods, you are really adding singleton instance methods to the class object for the type.</p>
<p>Ie, when you do something like:</p>
<pre>
class Cars
  def self.find_all
    ...
  end
</pre>
<p>You are actually creating a new object, of type Class which has a singleton method called 'find_all'. 'self' in the code above is the Class object, so def self.xxx is adding a singleton method to it.</p>
<p>This also explains the alternative syntax for adding class methods:</p>
<pre>
class Cars
  class << self
    def find_all
      ...
    end
  end
</pre>
<p>The same thing could be done by saying:</p>
<pre>
Cars = Class.new
Cars.instance_eval { def find_all; ... end; }
</pre>
<p>In Ruby, the type and class system is not very different from the normal objects you work with every day. I find this really quite cute and internally consistent.</p>
<p>The way the method search path works in ruby was also nicely explained in the book. Basically, finding a method starts at the top of the list below and stops as soon as a method with a matching name is found (ie, that responds to the message sent to the object):</p>
<ul>
<li>Singleton methods on the object</li>
<li>Methods defined by the object's class</li>
<li>Methods defined by modules mixed in to the class</li>
<li>Methods defined by parent class</li>
<li>Methods defined by modules mixed into parent class</li>
<li>Repeat checking parents until get to Object</li>
<li>Methods defined on Object</li>
<li>Methods defined on Kernel (module mixed into Object)</li>
</ul>
<p>This also explains why you can always call methods like 'p' from anywhere. They are coming from Kernel which is mixed in at the top of the inheritance tree for your object. Another case of internal consistency - there's no 'special' mechanism for these seeming globals.</p>
<p>Overall, I enjoyed the book and would recommend anyone having a read who has worked with Ruby and Rails but would like to dig a bit deeper.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/08/10/ruby-for-rails-by-david-black/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mephisto Contact Form Plugin Moved to GitHub</title>
		<link>http://jamescrisp.org/2009/08/10/mephisto-contact-form-plugin-moved-to-github/</link>
		<comments>http://jamescrisp.org/2009/08/10/mephisto-contact-form-plugin-moved-to-github/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 00:18:35 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Mephisto]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/08/10/mephisto-contact-form-plugin-moved-to-github/</guid>
		<description><![CDATA[Sorry the the confusion, anyone who has been checking out the the Mephisto Contact Form Plugin from the old SVN repository. The latest version with an update for Rails 2.3 is at:
http://github.com/jcrisp/mephisto_contact_form/tree/master
]]></description>
			<content:encoded><![CDATA[<p>Sorry the the confusion, anyone who has been checking out the the Mephisto Contact Form Plugin from the old SVN repository. The latest version with an update for Rails 2.3 is at:</p>
<p><a href="http://github.com/jcrisp/mephisto_contact_form/tree/master">http://github.com/jcrisp/mephisto_contact_form/tree/master</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/08/10/mephisto-contact-form-plugin-moved-to-github/feed/</wfw:commentRss>
		</item>
		<item>
		<title>“Now, Discover your Strengths” and “Strengthfinder”</title>
		<link>http://jamescrisp.org/2009/08/06/now-discover-your-strengths-and-strengthfinder/</link>
		<comments>http://jamescrisp.org/2009/08/06/now-discover-your-strengths-and-strengthfinder/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 07:09:54 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Soft Skills and Mind Hacks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/08/06/now-discover-your-strengths-and-strengthfinder/</guid>
		<description><![CDATA[A while back I bought a copy of Now, Discover your Strengths by Marcus Buckingham and Donald Clifton, and have only just got around to reading it. The book comes with a single-use code that lets you take an online personality test with 180 questions, with the aim of determining your 5 core strengths. The [...]]]></description>
			<content:encoded><![CDATA[<p>A while back I bought a copy of <a href="http://www.amazon.com/gp/product/0743201140?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0743201140">Now, Discover your Strengths</a> by Marcus Buckingham and Donald Clifton, and have only just got around to reading it. The book comes with a single-use code that lets you take an online personality test with 180 questions, with the aim of determining your 5 core strengths. The test takes about half an hour and is not onerous.</p>
<p>The book outlines one main idea. Find your natural talents and capitalize on these, building them up into strengths. Shape your work and life in ways that use your natural talents, as this will make you more effective, productive and happy. Although anyone can learn anything, people with a natural talent in an area are going to be able to reach a higher level of capability and success. Mitigate your weaknesses by partnering with people who have complementary strengths, developing a support system to help you, improving your skills in the area just enough to stop them from detracting from your strengths or simply stop doing things that play to your weaknesses.</p>
<p>The core concept of playing to your strengths is covered from many angles in the book and with supporting stories of successful people like Bill Gates and Warren Buffett. There is then a detailed description of each of the strengths that the online personality test can highlight. The last part of the book is interesting and focuses on building organisations which play to people's strengths, management of people with different strengths and some thoughts on the staff review process in organisations.</p>
<p>Overall, the book was a very quick read with low information density. The online test was fun. You can see my results below. I don't think it told me anything too new - I already know that I'm pretty analytical, like to learn, focus strongly on achieving tasks etc. The core idea about playing to and building your strengths does seem a good one from the personal satisfaction and cost/benefit point of view (assuming society values the areas you have talents in, and your areas of weakness don't get in the way too often).</p>
<hr/>
<p>Please note that the following text is Copyright 2000 The Gallup Organization.</p>
<p><strong>Analytical</strong><br />
Your Analytical theme challenges other people: “Prove it. Show me why what you are claiming is true.” In the face of this kind of questioning some will find that their brilliant theories wither and die. For you, this is precisely the point. You do not necessarily want to destroy other people’s ideas, but you do insist that their theories be sound. You see yourself as objective and dispassionate. You like data because they are value free. They have no agenda. Armed with these data, you search for patterns and connections. You want to understand how certain patterns affect one another. How do they combine? What is their outcome? Does this outcome fit with the theory being offered or the situation being confronted? These are your questions. You peel the layers back until, gradually, the root cause or causes are revealed. Others see you as logical and rigorous. Over time they will come to you in order to expose someone’s “wishful thinking” or “clumsy thinking” to your refining mind. It is hoped that your analysis is never delivered too harshly. Otherwise, others may avoid you when that “wishful thinking” is their own.<br />
Learner</p>
<p>You love to learn. The subject matter that interests you most will be determined by your other themes and experiences, but whatever the subject, you will always be drawn to the process of learning. The process, more than the content or the result, is especially exciting for you. You are energized by the steady and deliberate journey from ignorance to competence. The thrill of the first few facts, the early efforts to recite or practice what you have learned, the growing confidence of a skill mastered—this is the process that entices you. Your excitement leads you to engage in adult learning experiences—yoga or piano lessons or graduate classes. It enables you to thrive in dynamic work environments where you are asked to take on short project assignments and are expected to learn a lot about the new subject matter in a short period of time and then move on to the next one. This Learner theme does not necessarily mean that you seek to become the subject matter expert, or that you are striving for the respect that accompanies a professional or academic credential. The outcome of the learning is less significant than the “getting there.”</p>
<p><strong>Command</strong><br />
Command leads you to take charge. Unlike some people, you feel no discomfort with imposing your views on others. On the contrary, once your opinion is formed, you need to share it with others. Once your goal is set, you feel restless until you have aligned others with you. You are not frightened by confrontation; rather, you know that confrontation is the first step toward resolution. Whereas others may avoid facing up to life’s unpleasantness, you feel compelled to present the facts or the truth, no matter how unpleasant it may be. You need things to be clear between people and challenge them to be clear-eyed and honest. You push them to take risks. You may even intimidate them. And while some may resent this, labeling you opinionated, they often willingly hand you the reins. People are drawn toward those who take a stance and ask them to move in a certain direction. Therefore, people will be drawn to you. You have presence. You have Command.</p>
<p><strong>Focus</strong><br />
“Where am I headed?” you ask yourself. You ask this question every day. Guided by this theme of Focus, you need a clear destination. Lacking one, your life and your work can quickly become frustrating. And so each year, each month, and even each week you set goals. These goals then serve as your compass, helping you determine priorities and make the necessary corrections to get back on course. Your Focus is powerful because it forces you to filter; you instinctively evaluate whether or not a particular action will help you move toward your goal. Those that don’t are ignored. In the end, then, your Focus forces you to be efficient. Naturally, the flip side of this is that it causes you to become impatient with delays, obstacles, and even tangents, no matter how intriguing they appear to be. This makes you an extremely valuable team member. When others start to wander down other avenues, you bring them back to the main road. Your Focus reminds everyone that if something is not helping you move toward your destination, then it is not important. And if it is not important, then it is not worth your time. You keep everyone on point.</p>
<p><strong>Input</strong><br />
You are inquisitive. You collect things. You might collect information—words, facts, books, and quotations—or you might collect tangible objects such as butterflies, baseball cards, porcelain dolls, or sepia photographs. Whatever you collect, you collect it because it interests you. And yours is the kind of mind that finds so many things interesting. The world is exciting precisely because of its infinite variety and complexity. If you read a great deal, it is not necessarily to refine your theories but, rather, to add more information to your archives. If you like to travel, it is because each new location offers novel artifacts and facts. These can be acquired and then stored away. Why are they worth storing? At the time of storing it is often hard to say exactly when or why you might need them, but who knows when they might become useful? With all those possible uses in mind, you really don’t feel comfortable throwing anything away. So you keep acquiring and compiling and filing stuff away. It’s interesting. It keeps your mind fresh. And perhaps one day some of it will prove valuable.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/08/06/now-discover-your-strengths-and-strengthfinder/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Spying on Instance Variables in Ruby</title>
		<link>http://jamescrisp.org/2009/08/05/spying-on-instance-variables-in-ruby/</link>
		<comments>http://jamescrisp.org/2009/08/05/spying-on-instance-variables-in-ruby/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 07:26:45 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/08/05/spying-on-instance-variables-in-ruby/</guid>
		<description><![CDATA[A little while back, a few colleagues and I were spiking a proxy concept based on extending an existing web server. We wanted to check out an instance variable (eg, @very_secret) in a framework object which did not have an accessor. In the past, we'd used send (eg, secretive_object.send :hello_private) to get at privates, but [...]]]></description>
			<content:encoded><![CDATA[<p>A little while back, a few colleagues and I were spiking a proxy concept based on extending an existing web server. We wanted to check out an instance variable (eg, @very_secret) in a framework object which did not have an accessor. In the past, we'd used send (eg, secretive_object.send :hello_private) to get at privates, but send is only for methods. We were just digging around doing some debugging, so we opened the relevant class and added a public accessor for the instance variable to see what was happening. However, we thought there must be a more elegant way to do access instance variables outside the class, and one has just come to mind (at last!):</p>
<pre>
secretive_object.instance_eval { @very_secret }
</pre>
<p>instance_eval lets us run the code block in the context of secretive_object. Ie, self == secretive_object, so we can get at all the hidden stuff.</p>
<p>It's a rather different approach to other languages like C# and Java where accessing private variables and private methods are part of  a reflection/introspection API.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/08/05/spying-on-instance-variables-in-ruby/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Review: “Deploying Rails Applications” by Ezra Zygmuntowicz et al.</title>
		<link>http://jamescrisp.org/2009/08/02/deploying-rails-applications-by-ezra-zygmuntowicz-et-al/</link>
		<comments>http://jamescrisp.org/2009/08/02/deploying-rails-applications-by-ezra-zygmuntowicz-et-al/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 04:20:38 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/08/02/deploying-rails-applications-by-ezra-zygmuntowicz-et-al/</guid>
		<description><![CDATA[Deploying Rails Applications: A Step-by-Step Guide by Ezra Zygmuntowicz, Bruce Tate and Clinton Begin is a good read, if a little dated. It was published in May 2008, and you can see that things have moved on a little in the Rails world since then. None the less, quite a lot of the information is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/0978739205?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0978739205">Deploying Rails Applications: A Step-by-Step Guide</a> by Ezra Zygmuntowicz, Bruce Tate and Clinton Begin is a good read, if a little dated. It was published in May 2008, and you can see that things have moved on a little in the Rails world since then. None the less, quite a lot of the information is still relevant and useful.</p>
<p>The book covers some basic Rails and version control concerns at the start, then rapidly launches into chapters devoted to Rails hosting options available from shared hosts to virtual and dedicated servers. The advice given is good and is in line with my experiences. Unix configuration is given in depth which would be very handy if you had not set up a server before.  Next is a good discussion of Capistrano and automating deployments. The examples all use subversion. However, these days I expect the majority of Rails source code is pulled with Git. There is also a chapter on managing mongrels and setting up monitoring solutions. This is still relevant if you want to use mongrels, however these days <a href="http://www.modrails.com/">Passenger</a> is probably the best choice, and it does not have such complex management and configuration requirements. The scaling out chapter is useful and pulls together handy information including details on MySql replication/clustering. There's a chapter on deploying on Windows and also some suggestions around performance and profiling.</p>
<p>I haven't come across another book that brings together a structured collection of useful information to help you move from running rails locally to having a cluster of scalable production servers and the automated deployment process required to support it. Despite being too old to cover Git and Passenger, I'd still recommend having a read of this book if you're at the stage of planning to launch a Rails site or looking to scale your VPS up to a cluster.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/08/02/deploying-rails-applications-by-ezra-zygmuntowicz-et-al/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Linux VirtualBox vs Windows for Rails Dev</title>
		<link>http://jamescrisp.org/2009/02/21/linux-virtualbox-vs-windows-for-rails-dev/</link>
		<comments>http://jamescrisp.org/2009/02/21/linux-virtualbox-vs-windows-for-rails-dev/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 03:06:56 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Windows]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/02/21/linux-virtualbox-vs-windows-for-rails-dev/</guid>
		<description><![CDATA[So yes, everyone has heard that Mac OS X and TextMate is the epitome of Rails development, and that it is so awesome that it brings tears of joy to developers eyes, &#038;c. However, for those of us who either don’t have a Mac, or get to work on client provided hardware (often running Windows), [...]]]></description>
			<content:encoded><![CDATA[<p>So yes, everyone has heard that Mac OS X and TextMate is the epitome of Rails development, and that it is so awesome that it brings tears of joy to developers eyes, &#038;c. However, for those of us who either don’t have a Mac, or get to work on client provided hardware (often running Windows), there are a few options available.</p>
<p>Developing on Windows XP, with <a href="http://instantrails.rubyforge.org/">InstantRails</a> is workable. It is easy to get everything you need and have your apps up and running quickly. However, performance is, well, quite frankly, terrible for anything you do on the command line. Mainly, this bites when running tests, doing migrations, generating files etc. Performance running Mongrel is good enough for development. </p>
<p>What about <a href="http://www.cygwin.com/">Cygwin</a>? Subjectively, I found it provided similar speed to Windows Ruby/Rails.</p>
<p>So this brings us to virtualisation. Recently, I've been testing out <a href="http://www.virtualbox.org/">VirtualBox</a> running Ubuntu on top of Windows XP. This has had surprisingly good results. On the same machine, the virtual <a href="http://www.ubuntu.com/">Ubuntu</a> running Rails tasks has about 4 times (!!!) faster performance, even though it has less memory and system resources! </p>
<p>Here are some stats to give you and idea of the advantage.</p>
<p>Machine is a 2.4ghz quad core, 4gig of memory running Windows XP. Using VirtualBox 2.1.4 for virtualized Ubuntu Intrepid 64 bit, with 1.5gig of memory allocated. Figures are in seconds and approximate (taken with a wrist watch).</p>
<table cellpadding=2 cellspacing=0 border=1>
<tr>
<th>&nbsp;</th>
<th>generate scaffold</th>
<th>db:migrate with no changes</th>
<th>run tests for medium sized rails app</th>
</th>
</tr>
<tr>
<td>Windows XP &#038; Instant Rails</td>
<td>7</td>
<td>7</td>
<td>25</td>
</tr>
<tr>
<td>VirtualBox Ubuntu on same Windows XP</td>
<td>1.5</td>
<td>1.5</td>
<td>6</td>
</tr>
</table>
<p>Some of these commands / tests rely on hitting a MySQL database. However, I’m interested in overall development speed for both platforms, not in Ruby speed in particular, so I think it is fair game to include these in the results.</p>
<p>So if you want to do Rails Dev on Windows, I highly recommend trying a virtual machine running Linux!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/02/21/linux-virtualbox-vs-windows-for-rails-dev/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Vim with find file for Rails (like TextMate)</title>
		<link>http://jamescrisp.org/2009/02/21/vim-with-find-file-for-rails-like-textmate/</link>
		<comments>http://jamescrisp.org/2009/02/21/vim-with-find-file-for-rails-like-textmate/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 01:09:33 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/02/21/multi-tab-vim-with-find-file-like-textmate/</guid>
		<description><![CDATA[In a fit of TextMate jealousy, several months ago, I scoured the web for a way to get find-file functionality info my favourite Ruby/Rails editor, vim. I was very happy to find that Jamis Buck had developed an aweseome plugin do to this. It is a little fiddly to install, but worth the trouble. Here's [...]]]></description>
			<content:encoded><![CDATA[<p>In a fit of TextMate jealousy, several months ago, I scoured the web for a way to get find-file functionality info my favourite Ruby/Rails editor, <a href="http://www.vim.org/">vim</a>. I was very happy to find that Jamis Buck had developed an <a href="http://weblog.jamisbuck.org/2008/10/10/coming-home-to-vim">aweseome plugin</a> do to this. It is a little fiddly to install, but worth the trouble. Here's some simplified steps to get you going. </p>
<ul>
<li>Install Jamis's ruby gem
<pre>sudo gem install jamis-fuzzy_file_finder --source=http://gems.github.com</pre>
</li>
<li>Download this <a href="http://www.vim.org/scripts/download_script.php?src_id=9643">fuzzyfinder</a> script and pop it in your '~/.vim/plugin' directory. Note that the most recent versions of this script are incompatible with Jamis's plugin.</li>
<li>Grab the latest version of 'fuzzyfinder_textmate.vim' from <a href="http://github.com/jamis/fuzzyfinder_textmate/tree/master">http://github.com/jamis/fuzzyfinder_textmate/tree/master</a> and pop it in your '~/.vim/plugin' directory</li>
</ul>
<p>Then, if you want to have a similar sort of light-weight Rails 'IDE' I enjoy coding with, see my config files below:</p>
<p><b>.vimrc</b></p>
<pre>
source $VIMRUNTIME/vimrc_example.vim
behave xterm
set nu
set tabstop=2
set shiftwidth=2
set softtabstop=2
set ai
set expandtab
set smarttab
let g:rubycomplete_rails = 1

map f :FuzzyFinderTextMate&lt;CR&gt;
map n :tabnew&lt;CR&gt;
map c :tabclose&lt;CR&gt;
map m :tabnext&lt;CR&gt;

let g:fuzzy_ignore = "*.svn"
let g:fuzzy_ignore = "*.swp"
let g:fuzzy_ignore = "*.jpg"
let g:fuzzy_ignore = "*.gif"
let g:fuzzy_ignore = "*~"

set nobackup
</pre>
<p><b>.gvimrc</b></p>
<pre>
source ~/.vimrc
set selectmode=mouse
set columns=100
set lines=50
</pre>
<p>In this set up, there are no chords etc. Instead, when not in edit mode, 'n' will open a new tab. 'f' will let you find a new file to open in the current tab. 'c' will close the current tab and 'm' will move between tabs. So in a normal workflow, you might decide to swap the file in the current tab for a new one (simply press 'f'), or if you need another file open, hit 'n' for new tab, and then 'f' to load the relevant file. My text description doesn't do it justice, but I find this works very well to get you to the file you want quickly, and let you have the files you're interested in open all at the same time.</p>
<p>One last note, remember to start vim/gVim in the root of your rails directory.</p>
<p>Happy Vimming <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/02/21/vim-with-find-file-for-rails-like-textmate/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Slides from REST Talk at St George Bank</title>
		<link>http://jamescrisp.org/2009/01/29/slides-from-rest-talk-at-st-george-bank/</link>
		<comments>http://jamescrisp.org/2009/01/29/slides-from-rest-talk-at-st-george-bank/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 11:22:32 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[REST]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/01/29/slides-from-rest-talk-at-st-george-bank/</guid>
		<description><![CDATA[Thanks very much to Nigel for inviting me to present on REST at St George Bank in Kogarah, and to ThoughtWorks for the time in the middle of the day to give the talk. It was a fun session and the people attending asked quite a number of good questions. Here are the slides. Please [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks very much to <a href="http://nigel-eke.com/">Nigel</a> for inviting me to present on REST at St George Bank in Kogarah, and to ThoughtWorks for the time in the middle of the day to give the talk. It was a fun session and the people attending asked quite a number of good questions. Here are the <a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/10/rest-talk.ppt' title='REST talk'>slides</a>. Please note that they are about 10mb (thanks to all the images). There's some extra information in the "Notes" pane as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/01/29/slides-from-rest-talk-at-st-george-bank/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Review: RESTful PHP Web Services by Samisa Abeysinghe</title>
		<link>http://jamescrisp.org/2009/01/09/restful-php-web-services-by-samisa-abeysinghe/</link>
		<comments>http://jamescrisp.org/2009/01/09/restful-php-web-services-by-samisa-abeysinghe/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 04:33:47 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[REST]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2009/01/09/book-review-restful-php-web-services-by-samisa-abeysinghe/</guid>
		<description><![CDATA[Packt Publishing kindly sent me a copy of RESTful PHP Web Services by Samisa Abeysinghe to review. The book’s cover claims that it will help you "Learn the basic architectural concepts and steps through examples of consuming and creating RESTful web services in PHP". The book succeeds in providing simple steps and examples of creating [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/1847195520?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=211189&#038;creative=374929&#038;creativeASIN=1847195520"><img src="https://images-na.ssl-images-amazon.com/images/I/51d2CqPOy8L._SL160_.jpg" style="float: left; margin: 0.2em 8px 8px 0;" /></a><a href="http://www.packtpub.com/restful-php-web-services/book">Packt Publishing</a> kindly sent me a copy of <a href="http://www.amazon.com/gp/product/1847195520?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=211189&#038;creative=374929&#038;creativeASIN=1847195520">RESTful PHP Web Services by Samisa Abeysinghe</a> to review. The book’s cover claims that it will help you "Learn the basic architectural concepts and steps through examples of consuming and creating RESTful web services in PHP". The book succeeds in providing simple steps and examples of creating and consuming web services, but falls short on REST architectural concepts and design principles.</p>
<p>The book starts with a very brief introduction to the principles of REST, and rapidly moves on to a discussion of PHP tools frameworks. The introduction misses some important REST / RESTful web service concepts such as <a href="http://en.wikipedia.org/wiki/Hypermedia">hypermedia</a>, application vs resource state and the relevance of utilising HTTP headers and status codes. Some of the information in the introduction is confusing. For example, on page 12, it says  "Resources can have multiple representations that reflect different application states". This does sound a little odd – resources can have multiple representations, for example, for different requested content types. Representations should reflect resource state, not application state. Also, the coverage of HTTP verbs is misleading, especially when POST and PUT are discussed.</p>
<p>The next couple of chapters discuss PHP support for HTTP, using libraries such as CURL, and XML parsing strategies. The author chooses realistic examples for code samples, such as Flickr and Yahoo Maps clients. The last example given is quite cool – using earthquake latitudes and longitudes from an Australian government site to plot points on Yahoo maps. The example code is generally simple and easy to follow. However, it would have been nice to see some sort of separation between view and data access logic.</p>
<p>The following chapter is a worked example of building RESTful services for a library lending books. It is a good example, and becomes the basis for most future chapters. The resource design and URLs are reasonable, although it may have been nice to have "loans" as resources in their own right. Using links between resources, rather than just relying on known URLs would also benefit the design. </p>
<p>Later chapters cover alternative frameworks such as Zend and WSO2 using the library lending system as an example for code samples. These chapters are useful as they give an idea how the frameworks look when put in practice. It does look as though PHP and frameworks still have significant limitations around routing flexibility from the examples (eg, the .php extension seems to mandatory in URLs). There is also a chapter on debugging with tips around tools and troubleshooting XML parsing issues.</p>
<p>The writing style is generally clear and easy to read. There are occasionally some odd turns of phrase, such as on page 10: "AJAX makes Web applications to become more interactive, faster, and more user-friendly".</p>
<p>Overall, I would recommend this book to people wanting to write simple URI template based web services or clients in PHP, and also to people interested in getting an overview of libraries and frameworks currently available in the PHP ecosystem. To gain an understanding of the REST architectural constraints and designing good RESTful systems, I would recommend <a href="http://www.amazon.com/gp/product/0596529260?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=211189&#038;creative=374929&#038;creativeASIN=0596529260">RESTful Web Services</a>, and if you wanted to take it further, digging into <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm">Roy Fielding’s thesis</a> and the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">HTTP 1.1 Spec</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/01/09/restful-php-web-services-by-samisa-abeysinghe/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Review: JavaScript - The Good Parts by Douglas Crockford</title>
		<link>http://jamescrisp.org/2008/12/20/review-javascript-the-good-parts-by-douglas-crockford/</link>
		<comments>http://jamescrisp.org/2008/12/20/review-javascript-the-good-parts-by-douglas-crockford/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 11:57:36 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/12/20/review-javascript-the-good-parts-by-douglas-crockford/</guid>
		<description><![CDATA["JavaScript: The Good Parts" was kindly lent to me by my friend and colleague Dave Cameron. It was a highly informative read, and a good length at just under 150 pages. The aim of the book is to define an elegant, recommended subset of JavaScript that allows you to do everything you need, and work [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/0596517742?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=211189&#038;creative=374929&#038;creativeASIN=0596517742">"JavaScript: The Good Parts"</a> was kindly lent to me by my friend and colleague Dave Cameron. It was a highly informative read, and a good length at just under 150 pages. The aim of the book is to define an elegant, recommended subset of JavaScript that allows you to do everything you need, and work around problems in the language. The book is aimed at people who already have a good grasp of programming in other languages.</p>
<p>I learnt quite a bit from the book. Here are a few of the most important parts that come to mind:</p>
<ul>
<li>JavaScript has function scope, not block scope so it is best to declare variables at the top of functions.</li>
<li>It is important to put { on the same line as the block opening keyword (eg, function, if etc) rather than on the next line. Otherwise, you may run into problems with some JavaScript implementations auto-adding ; in the wrong place.</li>
<li>Using the === and !== operators are safer and better than the == and != operators as they do no coerce types.</li>
<li>The 'new' operator is a bad way to make new objects in JavaScript and should be avoided. Functions starting with a capital letter should always be called with the new operator by convention. Failing to do this will add all the functionality of the object you are trying to create to the global object (thanks to the this references)!</li>
<li>You can always pass any number of arguments to a function. Extra arguments are not bound to function parameters, missing arguments will be undefined. Inside the function all arguments are accessible using the 'arguments' variable which is an array-like object.</li>
<li>Lots of things are false. Eg, 0, NaN, empty string, null, and undefined.</li>
<li>hasOwnProperty(name) is great in for(property in object) loops to find members of your object rather inherited members.</li>
<li>Object.beget(someOtherObject) allows prototypal inheritance from someOtherObject.</li>
<li>JavaScript arrays are really just objects with numerical property names and the length property, so if you use a for in loop, you'll get indices in random order.</li>
<li>It is a good idea to 'namespace' your code in a single global variable for your application to avoid conflicts with other libraries. Eg, myApp = {}; myApp.myVariable = 5;</li>
<li>If you don't used var, a global variable is created.</li>
<li>Closures let you make information private and give you encapsulation.</li>
<li>Inner functions have access to the variables defined in an outer function.</li>
</ul>
<p>Creating objects with private data:</p>
<pre>
var incrementer = function() {
  var value = 0;

  return {
    increment: function (inc) {
      value += typeof inc === 'number' ? inc : 1;
    },
    getValue: function() {
      return value;
    }
  };
};

var myIncrementer = incrementer();
 </pre>
<p>Functional inheritance</p>
<pre>
var mammal = function(spec) {
  var that = {};

  that.getName = function() {
    return spec.name;
  };

  return that;
};

var myMammal = mammal({name: 'Fred'});
myMammal.getName() === 'Fred'

var cat = function(spec) {
  var that = mammal(spec);
  var super_getName = that.superior('getName');

  that.purr = function { /* new catty stuff */ };

  that.getName = function {
    return super_getName() + ' the Cat!';
  };

  return that;
};

var myCat = cat({name: 'Kitty'});
myCat.getName() === 'Kitty the Cat!'

// Helpers

Object.method('superior', function(name) {
  var that = this, method = that[name];
  return function() { return method.apply(that, arguments); };
});

Function.prototype.method = function(name, func) {
  this.prototype[name] = func;
  return this;
};
</pre>
<p>There were a few things that I thought could be improved in the book. First of all, although the structure was adequate, it did lend itself to repetition. For example, scope is covered on p36 (in Functions section) and p102 (Awful parts), with very similar words. Secondly, I did not find the frequent syntax diagrams added much to the narrative.</p>
<p>Despite these small blemishes, I'm glad to have read Crockford's book. I now understand much better which parts of JavaScript to use, and how to build good object oriented code in JavaScript.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/12/20/review-javascript-the-good-parts-by-douglas-crockford/feed/</wfw:commentRss>
		</item>
		<item>
		<title>XML: When to attribute and when to element?</title>
		<link>http://jamescrisp.org/2008/12/20/xml-when-to-attribute-and-when-to-element/</link>
		<comments>http://jamescrisp.org/2008/12/20/xml-when-to-attribute-and-when-to-element/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 09:09:28 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Design / Architecture]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/12/20/xml-when-to-attribute-and-when-to-element/</guid>
		<description><![CDATA[When defining an XML document, when are attributes most appropriate, and when are elements best? This is something that I've generally decided based more on intuition than a good set of rules. 
Recently, at work, the need has arisen to define quite a few XML message payloads. I've also had the good fortune to work [...]]]></description>
			<content:encoded><![CDATA[<p>When defining an XML document, when are attributes most appropriate, and when are elements best? This is something that I've generally decided based more on intuition than a good set of rules. </p>
<p>Recently, at work, the need has arisen to define quite a few XML message payloads. I've also had the good fortune to work with <a href="http://erik.doernenburg.com/">Erik Doernenburg</a> and we had a chat about attributes vs. elements. Largely thanks to Erik, here are some guidelines that could come in handy when making such a decision.</p>
<p>An attribute is best used to represent:</p>
<ul>
<li>an id</li>
<li>metadata (eg, like rel and class in HTML)</li>
<li>a value from a small, closed set of values which interpreting programs rely on (eg, values that end up as application constants)
</ul>
<p>If none of the above apply, an element would likely be the best choice.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/12/20/xml-when-to-attribute-and-when-to-element/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Green &amp; Red Local Builds (adding colour to the local build process)</title>
		<link>http://jamescrisp.org/2008/11/20/green-red-local-builds-adding-colour-to-the-local-build-process/</link>
		<comments>http://jamescrisp.org/2008/11/20/green-red-local-builds-adding-colour-to-the-local-build-process/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 12:13:45 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Testing]]></category>

		<category><![CDATA[Design / Architecture]]></category>

		<category><![CDATA[EDI]]></category>

		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/11/20/green-red-local-builds-adding-colour-to-the-local-build-process/</guid>
		<description><![CDATA[Well, who doesn't write tests and do continuous integration (CI) these days? Whether you use one of the many Cruise Control variants, or Team City or some other tool, you most likely get a handy colour coding of builds as either green or red (ie, good, or bad). But, you can take this a step [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/11/build.JPG' title='build.JPG'><img src='http://jamescrisp.org/wordpress/wp-content/uploads/2008/11/build.thumbnail.JPG' alt='build.JPG' style="float: left; margin-right: 6px;" /></a>Well, who doesn't write tests and do continuous integration (CI) these days? Whether you use one of the many Cruise Control variants, or Team City or some other tool, you most likely get a handy colour coding of builds as either green or red (ie, good, or bad). But, you can take this a step further! </p>
<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/11/redbuild.JPG' title='redbuild.JPG'><img src='http://jamescrisp.org/wordpress/wp-content/uploads/2008/11/redbuild.thumbnail.JPG' alt='redbuild.JPG'  style="float: left; margin-right: 6px;" /></a>Often on .NET projects, we have a little batch file that we run before checking in (often with a pause at the end so it can be run from a shortcut), to confirm that no tests are broken locally. Well, it's not much fun peering at the ugly Nant output (or whatever build system you use). Instead, it is quite easy to add a couple of lines to your batch file and  change the colour of the console to bright Red or bright Green depending on the success of the local build. It is great for telling what the result was at a glance. I can't claim credit the idea - it was something we used at <a href="http://www.cargowise.com/">EDI</a> for our custom build system, but here's some batch file code I whipped up which I can claim is all mine, every last GOTO of it! Enjoy <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>The following code uses NAnt, but you can replace it with MsBuild or any other build tool that returns a status code.</p>
<pre>
@echo off

color 07

tools\nant\NAnt.exe -buildfile:mybuild.build %*

IF ERRORLEVEL 1 goto RedBuild
IF ERRORLEVEL 0 goto GreenBuild

:RedBuild
color 4F
goto TheEnd

:GreenBuild
color 2F

:TheEnd
pause
</pre>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/11/20/green-red-local-builds-adding-colour-to-the-local-build-process/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Slides from ACS REST Talk</title>
		<link>http://jamescrisp.org/2008/10/01/slides-from-acs-rest-talk/</link>
		<comments>http://jamescrisp.org/2008/10/01/slides-from-acs-rest-talk/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 12:29:55 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[REST]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/10/01/slides-from-acs-rest-talk/</guid>
		<description><![CDATA[Thanks to everyone who came along to the REST talk at ACS tonight. Here are the slides. They are quite a big download (10mb) as a result of all the images. When you review them, you might want to turn on the "Notes" view as I've added some text to go along with the image [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to everyone who came along to the REST talk at <a href="http://www.acs.org.au/index.cfm?action=event&#038;area=9001&#038;temID=eventdetails&#038;eveID=10114821847938">ACS</a> tonight. Here are the <a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/10/rest-talk.ppt' title='REST talk'>slides</a>. They are quite a big download (10mb) as a result of all the images. When you review them, you might want to turn on the "Notes" view as I've added some text to go along with the image based slides.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/10/01/slides-from-acs-rest-talk/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sydney ALT.NET Launched &amp; Ruby Slides</title>
		<link>http://jamescrisp.org/2008/09/30/sydney-altnet-launched-ruby-slides/</link>
		<comments>http://jamescrisp.org/2008/09/30/sydney-altnet-launched-ruby-slides/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 13:31:57 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[ALT.NET]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/09/30/sydney-altnet-launched-ruby-slides/</guid>
		<description><![CDATA[This evening we had the first Sydney Alt.Net meeting. It went really well. Our venue at the ThoughtWorks offices was pretty packed with about 35 interested people coming along. We started with a discussion of news in the .NET space, and then broke for food. After that we had my presentation on Ruby &#038; Rails [...]]]></description>
			<content:encoded><![CDATA[<p>This evening we had the <a href="http://sydneyaltdotnet.blogspot.com/2008/09/and-we-away.html">first Sydney Alt.Net meeting</a>. It went really well. Our venue at the ThoughtWorks offices was pretty packed with about 35 interested people coming along. We started with a discussion of news in the .NET space, and then broke for food. After that we had my presentation on Ruby &#038; Rails from a .NET perspective, followed by <a href="http://richardsbraindump.blogspot.com/">Richard's</a> presentation on Rhino Mocks. We ended with a retrospective to gather feedback and thoughts for future meetings. Thanks to everyone for coming along and making it such a great night! And also a big thank you to ThoughtWorks for the venue, food and drink.</p>
<p>Here's the <a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/09/ruby-dotnet-talk.ppt'>slides from "Ruby and Rails from a .NET perspective"</a>. It's a bit hard to give you a transcript of the demos but here is a taste of some of the ruby commands we looked at today.</p>
<p><b>Basic IronRuby Console demo</b></p>
<pre>
4+4
"hello".class
$friends = ["James", "Richard", "Bill"]
$friends.find_all { |f| f.include? "a" }
$friends.collect { |f| f.length }
"-" * 100
$person_type = Struct.new(:name, :age, :sex)
$j = person_type.new("James", 27, "m")
</pre>
<p><b>Iron Ruby Calling WinForms</b></p>
<pre>
require 'System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Form = System::Windows::Forms::Form
MessageBox = System::Windows::Forms::MessageBox
Button = System::Windows::Forms::Button 

$b = Button.new
$b.text = "Hello Button"
$f = Form.new
$f.controls << $b
$f.show_dialog
</pre>
<p><b>Simple Rails App Demo</b></p>
<pre>
rails myapp
ruby script/generate scaffold Person name:string age:integer
rake db:migrate
ruby script/server
</pre>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/09/30/sydney-altnet-launched-ruby-slides/feed/</wfw:commentRss>
		</item>
		<item>
		<title>First Sydney ALT.NET Meeting on 30 Sept</title>
		<link>http://jamescrisp.org/2008/09/11/first-sydney-altnet-meeting-on-30-sept/</link>
		<comments>http://jamescrisp.org/2008/09/11/first-sydney-altnet-meeting-on-30-sept/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 01:07:54 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[ALT.NET]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/09/11/first-sydney-altnet-meeting-on-31-oct/</guid>
		<description><![CDATA[Exciting news! We now have an ALT.NET group in Sydney! Our first meeting is Tuesday 30 September. Meetings will be the last Tuesday of the month.
Rough agenda for the first meeting is:
6:00pm &#160;&#160;Meet &#038; Greet time and then Kick Off!
6:30pm &#160;&#160;"Ruby, Rails and IronRuby from a .NET perspective" (me).
7:00pm &#160;&#160;Break with food and drink
7:30pm &#160;&#160;"Mocking [...]]]></description>
			<content:encoded><![CDATA[<p>Exciting news! We now have an ALT.NET group in Sydney! Our first meeting is Tuesday 30 September. Meetings will be the last Tuesday of the month.</p>
<p>Rough agenda for the first meeting is:</p>
<p>6:00pm &nbsp;&nbsp;Meet &#038; Greet time and then Kick Off!<br />
6:30pm &nbsp;&nbsp;<em>"Ruby, Rails and IronRuby from a .NET perspective"</em> (me).<br />
7:00pm &nbsp;&nbsp;Break with food and drink<br />
7:30pm &nbsp;&nbsp;<em>"Mocking with Rhino Mocks 3.5"</em> (<a href="http://richardsbraindump.blogspot.com/">Richard Banks</a>).<br />
8:00pm &nbsp;&nbsp;Wrap up &#038; go home.</p>
<p><a href="http://thoughtworks.com">ThoughtWorks</a> is sponsoring the event with a nice office location in the CBD, and also pizza and beer. So if you're planning to come, please comment or send me or <a href="http://richardsbraindump.blogspot.com/">Richard Banks</a> a mail to help us get enough food and drinks for everyone.</p>
<p>Address is:<br />
Level 8, 51 Pitt Street<br />
Sydney NSW 2000 Australia<br />
<a href="http://maps.google.com/maps?f=q&#038;hl=en&#038;geocode=&#038;q=51+Pitt+Street,+Sydney+NSW+2000,+Australia">[Map]</a></p>
<p>ALT.NET is about designing and building the best solutions possible. This means continuous improvement, retrospection and often reaching outside the mainstream, considering Open Source frameworks and tools, Agile methodologies and ideas from other language communities such as Ruby, Java and Haskell.</p>
<p>For more info about ALT.NET, check out our <a href="http://sydneyaltdotnet.blogspot.com/">Sydney ALT.NET Blog</a>, and the main <a href="http://altnetpedia.com/">ALT.NET wiki</a>. </p>
<p>See you on the 30th!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/09/11/first-sydney-altnet-meeting-on-30-sept/feed/</wfw:commentRss>
		</item>
		<item>
		<title>REST and .NET talk at ACS on 1 October</title>
		<link>http://jamescrisp.org/2008/09/10/rest-and-net-talk-at-acs/</link>
		<comments>http://jamescrisp.org/2008/09/10/rest-and-net-talk-at-acs/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 03:52:13 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[REST]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/09/10/rest-and-net-talk-at-acs/</guid>
		<description><![CDATA[I'll be giving a talk at the ACS (in Sydney CBD) on 1 October, about REST, designing good RESTful systems and implementing them in .NET. It will be quite similar to the REST Patterns in .NET talk I gave at Tech Ed. For more information, please check out the blurb at the ACS site.
]]></description>
			<content:encoded><![CDATA[<p>I'll be giving a talk at the ACS (in Sydney CBD) on 1 October, about REST, designing good RESTful systems and implementing them in .NET. It will be quite similar to the <a href="http://jamescrisp.org/2008/08/07/tech-ed-talk-rest-patterns-and-net/">REST Patterns in .NET talk</a> I gave at Tech Ed. For more information, please check out the <a href="http://www.acs.org.au/index.cfm?action=event&#038;area=9001&#038;temID=eventdetails&#038;eveID=10114821847938">blurb at the ACS site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/09/10/rest-and-net-talk-at-acs/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Slides from Tech Ed “Rest Patterns and .NET” Talk</title>
		<link>http://jamescrisp.org/2008/09/05/slides-from-tech-ed-rest-patterns-and-net-talk/</link>
		<comments>http://jamescrisp.org/2008/09/05/slides-from-tech-ed-rest-patterns-and-net-talk/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 06:37:52 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[REST]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/09/05/slides-from-tech-ed-rest-patterns-and-net-talk/</guid>
		<description><![CDATA[Here's the slides from "REST Patterns and .NET". I've put some extra info in the notes on various slides, so suggest browsing with notes displayed.
You might also be interested in more information about the talk or the simple rest client with code I mentioned during the presentation.
]]></description>
			<content:encoded><![CDATA[<p>Here's the <a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/09/talk-teched.ppt' title='TechEd REST and .NET talk'>slides from "REST Patterns and .NET"</a>. I've put some extra info in the notes on various slides, so suggest browsing with notes displayed.</p>
<p>You might also be interested in <a href="http://jamescrisp.org/2008/08/07/tech-ed-talk-rest-patterns-and-net/">more information about the talk</a> or the <a href="http://jamescrisp.org/2008/08/08/simple-rest-client/">simple rest client with code</a> I mentioned during the presentation.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/09/05/slides-from-tech-ed-rest-patterns-and-net-talk/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Contact Form For Mephisto updated for Drax 0.8</title>
		<link>http://jamescrisp.org/2008/08/25/contact-form-for-mephisto-updated-for-drax-08/</link>
		<comments>http://jamescrisp.org/2008/08/25/contact-form-for-mephisto-updated-for-drax-08/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 05:23:31 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Mephisto]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/08/25/contact-form-for-mephisto-updated-for-drax-08/</guid>
		<description><![CDATA[Mephisto Drax (version 0.8) introduces breaking changes for plugins. I've just finished updating the contact / feedback form plugin. It's now working fine and tests passing. 
Installation instructions are the same as before except that the 'contact_notifier' has moved from the 'lib' directory to the 'app' directory. It still needs to be updated to include [...]]]></description>
			<content:encoded><![CDATA[<p>Mephisto Drax (version 0.8) introduces breaking changes for plugins. I've just finished updating the <a href="http://jamescrisp.org/2007/03/19/contact-feedback-form-plugin-for-mephisto/">contact / feedback form plugin</a>. It's now working fine and tests passing. </p>
<p>Installation instructions are the same as before except that the 'contact_notifier' has moved from the 'lib' directory to the 'app' directory. It still needs to be updated to include your destination email address for contact mails. </p>
<p>If you're a Mephisto plug-in developer, you might be interested in checking out my post on <a href="http://jamescrisp.org/2008/08/25/migrating-mephisto-plugins-to-drax-08/">migrating Mephisto plugins to Drax</a>. It's based on my experiences with the contact_form.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/08/25/contact-form-for-mephisto-updated-for-drax-08/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Migrating Mephisto Plugins to Drax 0.8</title>
		<link>http://jamescrisp.org/2008/08/25/migrating-mephisto-plugins-to-drax-08/</link>
		<comments>http://jamescrisp.org/2008/08/25/migrating-mephisto-plugins-to-drax-08/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 05:07:10 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Mephisto]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/08/25/migrating-mephisto-plugins-to-drax-08/</guid>
		<description><![CDATA[There have been some major changes to Mephisto in the latest release (0.8 Drax) that break existing plugins. If you're interested in migrating your existing plugin(s) over to Drax, read on.
Repository Move
First thing to note is that the Mephisto code base has moved from SVN to github. 
Plugin Architecture Changes
There is no longer a base [...]]]></description>
			<content:encoded><![CDATA[<p>There have been some major changes to Mephisto in the latest release (0.8 Drax) that break existing plugins. If you're interested in migrating your existing plugin(s) over to Drax, read on.</p>
<p><strong>Repository Move</strong><br />
First thing to note is that the Mephisto code base has moved from SVN to <a href="http://github.com/halorgium/mephisto/tree/master">github</a>. </p>
<p><strong>Plugin Architecture Changes</strong><br />
There is no longer a base class for Mephisto plugins. Instead, you create Mephisto plugins using Rails Engines. If you're migrating a pre-Drax plugin to Drax and Rails engines, you'll most likely need to:</p>
<ul>
<li>Remove your plugin file - there's no base class for it any more so you'll get errors like: 'superclass must be a Class (Module given) (TypeError)'</li>
<li>Move your routes into a 'routes.rb' file in your plugin root directory.</li>
<li>In your plugin root directory, create an 'app' directory, with 'views', 'models' and 'controllers' sub-directories. Move your code files into the appropriate folders in the 'app' directory. These will be auto-loaded.</li>
<li>Remove various lines in your init.rb which manually add your plugin file directories to the load paths, if you have these.</li>
<li>If you inherit from the ApplicationController, add '<a href="http://dev.rubyonrails.org/ticket/6001">unloadable</a>' to your controller class. This will fix errors in development mode like 'A copy of ApplicationController has been removed from the module tree but is still active!'</li>
<p><strong>An example</strong><br />
You can have a look at my <a href="http://mephisto-contact-form-plugin.googlecode.com/svn/plugins/mephisto_contact_form">contact_form plugin code</a>. Revision 18 is before Drax and engines and uses the old approach. Revisions 19 and later are using Rails engines and will work with Drax.</p>
<p><strong>UPDATE:</strong> Latest code at GitHub<br />
<a href="http://github.com/jcrisp/mephisto_contact_form/tree/master">http://github.com/jcrisp/mephisto_contact_form/tree/master</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/08/25/migrating-mephisto-plugins-to-drax-08/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Simple REST Client</title>
		<link>http://jamescrisp.org/2008/08/08/simple-rest-client/</link>
		<comments>http://jamescrisp.org/2008/08/08/simple-rest-client/#comments</comments>
		<pubDate>Fri, 08 Aug 2008 03:42:42 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[REST]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/08/08/simple-rest-client/</guid>
		<description><![CDATA[While preparing for my upcoming REST talk, I made a basic REST client. It's nothing special but allows you to set the verb, request body and see the status code and all the headers on the response. It's quite handy for debugging and exploration of RESTful services. 
Feel free to download the:

Rest Client Code
Rest Client [...]]]></description>
			<content:encoded><![CDATA[<p>While preparing for my upcoming <a href="http://jamescrisp.org/2008/08/07/tech-ed-talk-rest-patterns-and-net/">REST talk</a>, I made a basic REST client. It's nothing special but allows you to set the verb, request body and see the status code and all the headers on the response. It's quite handy for debugging and exploration of RESTful services. </p>
<p>Feel free to download the:</p>
<ul>
<li><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/08/restclient.zip' title='Rest Client Code'>Rest Client Code</a></li>
<li><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/08/restclient.exe' title='Rest Client Executable'>Rest Client Compiled Executable</a></li>
</ul>
<p>Hope it is useful and saves you having to whip up your own little client!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/08/08/simple-rest-client/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RiskAssess - Risk Assessments for Schools</title>
		<link>http://jamescrisp.org/2008/08/07/riskassess-risk-assessments-for-schools/</link>
		<comments>http://jamescrisp.org/2008/08/07/riskassess-risk-assessments-for-schools/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 13:10:35 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[RiskAssess]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/08/07/riskassess-risk-assessments-for-schools/</guid>
		<description><![CDATA[In my spare time, I've been developing RiskAssess, an online risk assessment system for schools. RiskAssess helps teachers and lab assistants to quickly and easily produce risk assessments for laboratory experiments which meet Australian standards. RiskAssess should help decrease the number of accidents in school laboratories, and also help schools meet legal requirements. 
I'm pleased [...]]]></description>
			<content:encoded><![CDATA[<p>In my spare time, I've been developing <a href="http://riskassess.com.au">RiskAssess</a>, an online risk assessment system for schools. <a href="http://riskassess.com.au">RiskAssess</a> helps teachers and lab assistants to quickly and easily produce risk assessments for laboratory experiments which meet Australian standards. <a href="http://riskassess.com.au">RiskAssess</a> should help decrease the number of accidents in school laboratories, and also help schools meet legal requirements. </p>
<p>I'm pleased to say that the site is now well and truly launched and we have schools doing risk assessments every day using <a href="http://riskassess.com.au">RiskAssess</a>. There's still much to do and many new features to add, but so far we've had very positive feedback from the schools using the system. </p>
<p>On the technical side, <a href="http://riskassess.com.au">RiskAssess</a> is a Ruby on Rails site.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/08/07/riskassess-risk-assessments-for-schools/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tech Ed Talk: REST Patterns and .NET</title>
		<link>http://jamescrisp.org/2008/08/07/tech-ed-talk-rest-patterns-and-net/</link>
		<comments>http://jamescrisp.org/2008/08/07/tech-ed-talk-rest-patterns-and-net/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 01:35:30 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[REST]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/08/07/tech-ed-talk-rest-patterns-and-net/</guid>
		<description><![CDATA[I'll be giving a talk at Tech Ed this year on REST and how it can be implemented in .NET, much inspired by the thoughts of Jim Webber on good RESTful web services, and Garr Reynolds on the "Zen" presentation style. Here's some more info:
REST Patterns and .NET
Sydney Convention Centre, Darling Harbour
5 September 2008
10:15am - [...]]]></description>
			<content:encoded><![CDATA[<p>I'll be giving a talk at Tech Ed this year on REST and how it can be implemented in .NET, much inspired by the thoughts of <a href="http://jim.webber.name">Jim Webber</a> on good RESTful web services, and <a href="http://www.presentationzen.com/">Garr Reynolds</a> on the "Zen" presentation style. Here's some more info:</p>
<div style="border-left: 2px solid grey; margin-left: 2px; padding-left: 5px;"><strong>REST Patterns and .NET</strong></p>
<p><em>Sydney Convention Centre, Darling Harbour</em><br />
5 September 2008<br />
10:15am - 11:30am<br />
(ARC306)</p>
<p>REST has sparked furious debate, and reactions from fan-boy adoration to hate. As the arguments quiet and the dust settles, it is becoming clear that the RESTful style is a viable choice for the Enterprise. Framework support is growing rapidly. WCF now provides basic REST support. Meanwhile, the budding MVC framework opens the door to building services which leverage hypermedia. This talk will leave you with an understanding of the RESTful architectural style and provide you with recommendations on designing and building both simple and hypermedia driven web services in .NET.</p></div>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/08/07/tech-ed-talk-rest-patterns-and-net/feed/</wfw:commentRss>
		</item>
		<item>
		<title>F-Secure Optus Internet Suite - To be avoided!</title>
		<link>http://jamescrisp.org/2008/07/06/f-secure-optus-internet-suite-avoid-it/</link>
		<comments>http://jamescrisp.org/2008/07/06/f-secure-optus-internet-suite-avoid-it/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 00:23:46 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/07/06/f-secure-optus-internet-suite-avoid-it/</guid>
		<description><![CDATA[Optus, my ISP, is kind enough to give subscribers a free copy of F-Secure's security suite which offers anti-virus, anti-spam and firewall. I read some half decent reviews of the product so I thought I'd install it and give it a go. Unfortunately, it was fraught with problems. First of all, after installing I got [...]]]></description>
			<content:encoded><![CDATA[<p>Optus, my ISP, is kind enough to give subscribers a free copy of F-Secure's security suite which offers anti-virus, anti-spam and firewall. I read some half decent reviews of the product so I thought I'd install it and give it a go. Unfortunately, it was fraught with problems. First of all, after installing I got a blue screen on reboots. After uninstalling AVG (my previous anti-virus) in safe mode, my computer could boot. Next, I tried to do a full system scan, but the F-Secure automatic update kicked in at the same time and it crashed the scanner. So, I rebooted, and tried a full system scan. I tried twice, but each time, it hung on a random .class (compiled Java) from GlassFish. Not great. So I went to the F-Secure website to submit a bug report. I filled in the form, and couldn't submit it because one of the drop down lists which was mandatory was disabled in Opera. I then thought I'd try the site in IE7, but IE7 just hung, presumably thanks to F-Secure's firewall. </p>
<p>Overall, I would strongly suggest that you do not bother to try the F-Secure product suite, even if it is offered to you for free.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/07/06/f-secure-optus-internet-suite-avoid-it/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Long Tail by Chris Anderson</title>
		<link>http://jamescrisp.org/2008/06/09/the-long-tail-by-chris-anderson/</link>
		<comments>http://jamescrisp.org/2008/06/09/the-long-tail-by-chris-anderson/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 12:29:51 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Soft Skills and Mind Hacks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/06/09/the-long-tail-by-chris-anderson/</guid>
		<description><![CDATA[Just finished reading "The Long Tail - How Endless Choice is Creating Unlimited Demand" by Chris Anderson. In summary, the long tail is about selling small volumes of a vast variety of items instead of large volumes of a small number of "hits". This possible when the cost of distribution to geographically distant customers is [...]]]></description>
			<content:encoded><![CDATA[<p>Just finished reading <a href="http://www.amazon.com/gp/product/1401309666?ie=UTF8&#038;tag=yourweddpres-20&#038;linkCode=as2&#038;camp=211189&#038;creative=374929&#038;creativeASIN=1401309666">"The Long Tail - How Endless Choice is Creating Unlimited Demand"</a> by Chris Anderson. In summary, the long tail is about selling small volumes of a vast variety of items instead of large volumes of a small number of "hits". This possible when the cost of distribution to geographically distant customers is low and the cost of storage for stock is not a concern (eg, intellectual property in electronic format, JIT manufacture). Popular companies capitalising on the long tail include eBay, Amazon, Google Adwords and Lulu.</p>
<p>The book has a lot of interesting stories and statistics but tends to repeat itself often. The long tail idea is probably not new to most readers these days, and I think if you're familiar with Amazon, there's little that comes as a surprise. However, I did find an interesting section in the book about the tyranny of choice. Anderson suggests that choice is good, customers want choice, and choice is only a problem if you don't know what to choose to suit your taste. Hence, an important part of a long tail business is helping people find what they want (ie, filter out noise) in all the vast array of choices. He suggests using user reviews, rankings, sorting etc as means to help people find the "best" choice for them. I also hadn't come across <a href="http://www.lulu.com/">Lulu</a> before - looks worth checking out, a site for mini self-publishing.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/06/09/the-long-tail-by-chris-anderson/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Bounded Actions Using Lambda - IDisposable is old and ugly!</title>
		<link>http://jamescrisp.org/2008/05/26/bounded-actions-using-lambda-idisposable-is-old-and-ugly/</link>
		<comments>http://jamescrisp.org/2008/05/26/bounded-actions-using-lambda-idisposable-is-old-and-ugly/#comments</comments>
		<pubDate>Mon, 26 May 2008 13:17:37 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/05/26/bounded-actions-using-lambda-idisposable-is-old-and-ugly/</guid>
		<description><![CDATA[In .NET 2, it was all the rage to make hand-crafted, clever IDisposables that let you do a bounded action with clean up. Eg,

void SomeMethod()
{
        using (new SetCursorToWaitEggTimer())
        {
            VerySlowOperation();
 [...]]]></description>
			<content:encoded><![CDATA[<p>In .NET 2, it was all the rage to make hand-crafted, clever IDisposables that let you do a bounded action with clean up. Eg,</p>
<pre>
void SomeMethod()
{
        using (new SetCursorToWaitEggTimer())
        {
            VerySlowOperation();
        }
}

void VerySlowOperation()
{
    ... etc ...
}
</pre>
<p>This was kind of cute - you could make sure that, even if an exception was thrown, your clean up (eg, changing cursor back to normal) would occur. Implementing the IDisposable was a bit ugly but consuming it wasn't bad.</p>
<p>Now, with the sexy C# 3 syntax, you can do something similar much more elegantly. Eg,</p>
<pre>
void SomeMethod()
{
       DoWithWaitEggTimer(VerySlowOperation);
}

void DoWithWaitEggTimer(Action action)
{
    try
    {
        Mouse.OverrideCursor = Cursors.Wait;
        action();
    }
    finally
    {
        Mouse.OverrideCursor = null;
    }
}
</pre>
<p>If you're feeling like more adventures, you can also start passing these delegates around and injecting them. For example:</p>
<pre>
class SomeClass
{
    public Action<Action> RunSlowCode
    {
    	get { return runSlowCode ?? new Action<Action>(a => a.Invoke()); }
    	set { runSlowCode = value; }
    }
    Action<Action> runSlowCode;

    void DoSomethingSlow()
    {
         RunSlowCode(PullDataFromExternalSystem);
    }
}
</pre>
<p>This approach allows you to inject the delegate for what happens when slow code is run. So you could inject DoWithWaitEggTimer() or something new like DoWithWaitMessageDisplayedToUser(). Similarly, it could be used for unit testing or injecting between layers in your application.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/05/26/bounded-actions-using-lambda-idisposable-is-old-and-ugly/feed/</wfw:commentRss>
		</item>
		<item>
		<title>C# Default Access Modifier for Class Members - and drop that private habit!</title>
		<link>http://jamescrisp.org/2008/05/26/c-default-access-modifier-for-class-members-and-drop-that-private-habit/</link>
		<comments>http://jamescrisp.org/2008/05/26/c-default-access-modifier-for-class-members-and-drop-that-private-habit/#comments</comments>
		<pubDate>Mon, 26 May 2008 12:39:28 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/05/26/c-default-access-modifier-for-class-members-and-drop-that-private-habit/</guid>
		<description><![CDATA[The default access modifier for the members of a C# class (eg, fields, methods, and properties) is 'private'. As such, I recommend never using the redundant 'private' keyword for class members. Leaving off the private nicely separates your privates from your public/inheritable interface in syntax highlighting. It also saves people having to read redundant code [...]]]></description>
			<content:encoded><![CDATA[<p>The default access modifier for the members of a C# class (eg, fields, methods, and properties) is 'private'. As such, I recommend never using the redundant 'private' keyword for class members. Leaving off the private nicely separates your privates from your public/inheritable interface in syntax highlighting. It also saves people having to read redundant code - you wouldn't want your code to be full of un-needed casts, or redundant 'this.' references, would you?</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/05/26/c-default-access-modifier-for-class-members-and-drop-that-private-habit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>WPF Control Inheritance With Generics</title>
		<link>http://jamescrisp.org/2008/05/26/wpf-control-inheritance-with-generics/</link>
		<comments>http://jamescrisp.org/2008/05/26/wpf-control-inheritance-with-generics/#comments</comments>
		<pubDate>Mon, 26 May 2008 12:19:17 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[WPF]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/05/26/wpf-control-inheritance-with-generics/</guid>
		<description><![CDATA[Working in WPF is quite exciting - there's a lot of new possibilities, especially with easy control composition, much improved binding and Expression Blend to make sexy interfaces. One of the things you're likely to want to do though, when writing anything more than a toy application, is to have a base class for your [...]]]></description>
			<content:encoded><![CDATA[<p>Working in WPF is quite exciting - there's a lot of new possibilities, especially with easy control composition, much improved binding and Expression Blend to make sexy interfaces. One of the things you're likely to want to do though, when writing anything more than a toy application, is to have a base class for your UserControls or Windows, to share common functionality. It is also quite likely you will want to use generics in conjunction with control inheritance. With both the code behind, and the XAML, it's not immediately obvious how to do generic inheritance. It is a bit fiddly to get going, and sometimes the errors are not helpful. Here's a simple example that outlines how to bring it together.</p>
<p><br/></p>
<p><b>The base control</b></p>
<pre>
namespace WpfGenericsDemo
{
    public class BaseUserControl&lt;T&gt; : UserControl where T : IPresenter
    {
        public BaseUserControl()
        {
            ... various configurations ...
        }

         ... Awesome functionality to share ...
    }
}
</pre>
<p><br/></p>
<p><b>The child control code-behind</b></p>
<pre>
namespace WpfGenericsDemo
{
    public partial class ChildUserControl : BaseUserControl&lt;ChildPresenter&gt;
    {
        public ChildUserControl()
        {
            InitializeComponent();
        }

         ... More code ...
    }
}
</pre>
<p><br/></p>
<p><b>The child control XAML</b></p>
<pre>
&lt;WpfGenericsDemo:BaseUserControl x:Class="WpfGenericsDemo.ChildUserControl"
    x:TypeArguments="WpfGenericsDemo:ChildPresenter"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfGenericsDemo="clr-namespace:WpfGenericsDemo"&gt;

    ... The rest of your awesome XAML ...

&lt;/WpfGenericsDemo:BaseUserControl&gt;
</pre>
<p><br/></p>
<p>
<b>Notes</b></p>
<ul>
<li>Your top level node is the parent class of the control you want to create (eg, BaseUserControl). You specify the control class you want to create with 'x:class' (eg, ChildUserControl)</li>
<li>'x:TypeArguments' is the way you specify the generic type (eg, ChildPresenter)</li>
<li>You need to namespace your classes - eg, with 'xmlns:WpfGenericsDemo' which uses a clr-namespace style reference</li>
<li>Only your top level node can be genericised in XAML</li>
<p><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/05/26/wpf-control-inheritance-with-generics/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Treo 650 phone radio turns off by itself - a solution!</title>
		<link>http://jamescrisp.org/2008/04/20/treo-650-phone-radio-turns-off-by-itself-a-solution/</link>
		<comments>http://jamescrisp.org/2008/04/20/treo-650-phone-radio-turns-off-by-itself-a-solution/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 12:21:11 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/04/20/treo-650-phone-radio-turns-off-by-itself-a-solution/</guid>
		<description><![CDATA[Recently, I've been disappointed to find my Treo 650 turning off the phone radio by itself. If I was lucky, I heard the melodic sound that means "radio now off", and then I manually turned the radio back on. If I was unlucky, I didn't hear it, and missed phone calls and messages.
It seems that [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I've been disappointed to find my Treo 650 turning off the phone radio by itself. If I was lucky, I heard the melodic sound that means "radio now off", and then I manually turned the radio back on. If I was unlucky, I didn't hear it, and missed phone calls and messages.</p>
<p>It seems that the cause is that the Treo 650 SIM case gets looser with wear, and any break in connection between the SIM and the phone causes the phone radio to be deactivated. The solution is pretty easy, and described at the end of a <a href="http://mytreo.net/treofaq/TroubleShooting">FAQ</a> I came across. In summary, take out the SIM tray from the phone, remove the SIM. Put several layers of paper (cut small to fit) in the SIM tray, and then clip the SIM back on top. When you put the SIM tray back into your phone, it should work reliably again, with no more random turn-offs! </p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/04/20/treo-650-phone-radio-turns-off-by-itself-a-solution/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Loan Calulator: Monthly repayment and interest breakdown</title>
		<link>http://jamescrisp.org/2008/04/14/loan-calulator-monthly-repayment-and-interest-breakdown/</link>
		<comments>http://jamescrisp.org/2008/04/14/loan-calulator-monthly-repayment-and-interest-breakdown/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 03:27:49 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Finance]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/04/14/loan-calulator-monthly-repayment-and-interest-breakdown/</guid>
		<description><![CDATA[Wondering if your loan repayment calculations have been performed correctly this month, taking into account interest rate rises and extra repayments? You might be interested in giving my monthly loan calculator a go.
As my home loan provider doesn't show balances online, and only sends statements every 6 months, I like to ring up every month [...]]]></description>
			<content:encoded><![CDATA[<p>Wondering if your loan repayment calculations have been performed correctly this month, taking into account interest rate rises and extra repayments? You might be interested in giving my <a href="http://loancalculator.jamescrisp.org">monthly loan calculator</a> a go.</p>
<p>As my home loan provider doesn't show balances online, and only sends statements every 6 months, I like to ring up every month or two to make sure things are on track. I used to calculate interest, new balances etc in a spreadsheet / calculator but spent an afternoon writing a little Rails app to calculate it for me. Hopefully my little <a href="http://loancalculator.jamescrisp.org">monthly loan calculator</a> is of some use to you too.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/04/14/loan-calulator-monthly-repayment-and-interest-breakdown/feed/</wfw:commentRss>
		</item>
		<item>
		<title>NUnit Test Runners Were Not All Made Equal</title>
		<link>http://jamescrisp.org/2008/04/08/nunit-test-runners-were-not-all-made-equal/</link>
		<comments>http://jamescrisp.org/2008/04/08/nunit-test-runners-were-not-all-made-equal/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 07:26:11 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Testing]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/04/08/nunit-test-runners-were-not-all-made-equal/</guid>
		<description><![CDATA[NUnit tests can be run using a variety of different runners. Some common ones are:

NUnit GUI
Test Driven .NET
Resharper test runner
NUnit MS Build Task

The NUnit GUI and Test Driven create a new instance of the test class for each test run. This leads to more isolation but potentially slower performance.
Resharper and NUnit MSBuild Task re-use the [...]]]></description>
			<content:encoded><![CDATA[<p>NUnit tests can be run using a variety of different runners. Some common ones are:</p>
<ul>
<li><a href="http://www.nunit.org/">NUnit GUI</a></li>
<li><a href="http://www.testdriven.net/">Test Driven .NET</a></li>
<li><a href="http://www.jetbrains.com/resharper/">Resharper test runner</a></li>
<li><a href="http://msbuildtasks.tigris.org/">NUnit MS Build Task</a></li>
</ul>
<p>The NUnit GUI and Test Driven create a new instance of the test class for each test run. This leads to more isolation but potentially slower performance.</p>
<p>Resharper and NUnit MSBuild Task re-use the same instance of the test class when running each test in the class. This can lead to unintended interaction between tests. Using these runners, it is vital to to assign initial values to instance variables in SetUp, rather than when they are defined or in the constructor.</p>
<p>If you use a mix of different test runners, you can end up with tests that pass on some machines and fail on others (eg, Test Driven locally works fine, but you use NUnit MSBuild Task on your build box and get intermittent failures).</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/04/08/nunit-test-runners-were-not-all-made-equal/feed/</wfw:commentRss>
		</item>
		<item>
		<title>NUnit SetUp Attribute and Subclassed Test Cases</title>
		<link>http://jamescrisp.org/2008/04/08/nunit-setup-attribute-and-subclassed-test-cases/</link>
		<comments>http://jamescrisp.org/2008/04/08/nunit-setup-attribute-and-subclassed-test-cases/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 07:05:44 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Testing]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/04/08/nunit-setup-attribute-and-subclassed-test-cases/</guid>
		<description><![CDATA[If you have a ChildTestCase class that inherits from a ParentTestCase class, and both of these have a SetUp method, marked with the [SetUp] attribute, would you expect both to be called? If so, you would be sadly disappointed. Only the SetUp method of the ChildTestCase will be called, and the SetUp in the ParentTestCase [...]]]></description>
			<content:encoded><![CDATA[<p>If you have a ChildTestCase class that inherits from a ParentTestCase class, and both of these have a SetUp method, marked with the [SetUp] attribute, would you expect both to be called? If so, you would be sadly disappointed. Only the SetUp method of the ChildTestCase will be called, and the SetUp in the ParentTestCase will be ignored. </p>
<p>According to the <a href="http://www.nunit.org/index.php?p=setup&#038;r=2.2.10">NUnit documentation on the Set Up attribute</a>, this is intended behaviour:</p>
<blockquote><p>
If you wish to add more SetUp functionality in a derived class you need to mark the method with the appropriate attribute and then call the base class method.
</p></blockquote>
<p>An alternative approach to get all your SetUps called is to have a base TestCase class define a protected virtual SetUp() (with the SetUp attribute), which all child classes override (and call base on their first line).</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/04/08/nunit-setup-attribute-and-subclassed-test-cases/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sybase Adaptive Server 12.5.3 SQL (Un)Supported Features</title>
		<link>http://jamescrisp.org/2008/04/08/sybase-adaptive-server-1253-sql-unsupported-features/</link>
		<comments>http://jamescrisp.org/2008/04/08/sybase-adaptive-server-1253-sql-unsupported-features/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 02:22:55 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/04/08/sybase-adaptive-server-1253-sql-unsupported-features/</guid>
		<description><![CDATA[Sybase has some unusual features:

Column names and table names are case sensitive
Subqueries cannot include TOP 1 or ORDER BY
Queries with max(COLUMN_NAME) and an ORDER BY seem to ignore the WHERE clause. Removing ORDER BY seems to fix this.
Column names are 30 characters max
Join syntax is: left_table [inner &#124; left [outer] &#124; right [outer]] join right_table [...]]]></description>
			<content:encoded><![CDATA[<p>Sybase has some unusual features:</p>
<ul>
<li>Column names and table names are case sensitive</li>
<li>Subqueries cannot include TOP 1 or ORDER BY</li>
<li>Queries with max(COLUMN_NAME) and an ORDER BY seem to ignore the WHERE clause. Removing ORDER BY seems to fix this.</li>
<li>Column names are 30 characters max</li>
<li>Join syntax is: left_table [inner | left [outer] | right [outer]] join right_table on left_column_name  = right_column_name</li>
<li>Can't do boolean operations in SELECT (eg, =, > <), but can do mathematical operations (eg, +, -) in SELECT clause</li>
</ul>
<p><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/04/08/sybase-adaptive-server-1253-sql-unsupported-features/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Thoughts from Process Consulting</title>
		<link>http://jamescrisp.org/2008/04/06/thoughts-from-process-consulting/</link>
		<comments>http://jamescrisp.org/2008/04/06/thoughts-from-process-consulting/#comments</comments>
		<pubDate>Sun, 06 Apr 2008 07:51:27 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Soft Skills and Mind Hacks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/04/06/thoughts-from-process-consulting/</guid>
		<description><![CDATA[Just finished reading "Process Consulting" by Alan Weiss, lent to me by my talented colleague, Darren Smith. The book is concerned more with general consulting, not IT consulting or IT methodologies. I found the bigger picture view in Weiss's book enlightening and helpful in evaluating and questioning my own consulting practices. Here's a few thoughts [...]]]></description>
			<content:encoded><![CDATA[<p>Just finished reading <a href="http://www.amazon.com/Process-Consulting-Implement-Successful-Consultant/dp/0787955124">"Process Consulting"</a> by Alan Weiss, lent to me by my talented colleague, <a href="http://www.bunkandrambling.com">Darren Smith</a>. The book is concerned more with general consulting, not IT consulting or IT methodologies. I found the bigger picture view in Weiss's book enlightening and helpful in evaluating and questioning my own consulting practices. Here's a few thoughts from the book:</p>
<ul>
<li>Remember that you are not the change agent. The client personnel are the change agents. You are the catalyst, but they are accountable for enduring change. Don't be a hero...</li>
<li>Cute phrases and pithy slogans don't change behaviour. Aligning people's objectives behind corporate objectives and supporting that behaviour with metrics and rewards will usually gain their attention. Rapidly.</li>
<li>Is it really progress if we teach a cannibal to use a knife and fork? (from Stanislaw Lem, quoted by Weiss)</li>
<li>At the outset of any change process, immediately after agreement with the buyer, identify and "recruit" these key positions [hierarchical leaders, front line management, respected leaders and experts]. Use the buyer's clout if you must. The most crucial factor in organizational change occurs prior to implementation: It's the conceptual agreement and acknowledged self-interest among the few people who actually have their hands on the controls.</li>
<li>[Regarding change,] neutral is as bad as negative, since the default position for everyone else will always be the old behaviour.</li>
<li>Don't be anxious to "make change". If you have a six month window, for example, invest at least the first month or more aligning your support and key sponsors and establishing their accountabilities. The more time you take with critical sponsors, the faster you will ultimately create change.</li>
<li>When you find someone micromanaging, it is almost always because of a lack of trust. If you don't do the job the way he or she would do it, you must be doing it incorrectly. If the leader has trust in subordinates, simply providing the goals should be sufficient.</li>
</ul>
<p><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/04/06/thoughts-from-process-consulting/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sydney BarCamp 3 this Weekend!</title>
		<link>http://jamescrisp.org/2008/04/03/sydney-barcamp-3-this-weekend/</link>
		<comments>http://jamescrisp.org/2008/04/03/sydney-barcamp-3-this-weekend/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 11:33:17 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Talks]]></category>

		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/04/03/sydney-barcamp-3-this-weekend/</guid>
		<description><![CDATA[BarCamp Sydney is two days long this year, and will span the whole of the coming weekend (5-6 April). I'll be there on Saturday. It's usually quite a fun event, lots of good sessions and you're quite free to move around and find something that interests you. Part of the BarCamp manifesto is that you [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.barcampsydney.org/">BarCamp Sydney</a> is two days long this year, and will span the whole of the coming weekend (5-6 April). I'll be there on Saturday. It's usually quite a fun event, lots of good sessions and you're quite free to move around and find something that interests you. Part of the BarCamp manifesto is that you should also contribute as well as listen - I'll probably give a JRuby talk and demo. </p>
<p>Hope to see you at BarCamp!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/04/03/sydney-barcamp-3-this-weekend/feed/</wfw:commentRss>
		</item>
		<item>
		<title>“JRuby: Enterprise 2.0″ Slides</title>
		<link>http://jamescrisp.org/2008/03/07/jruby-enterprise-20-slides/</link>
		<comments>http://jamescrisp.org/2008/03/07/jruby-enterprise-20-slides/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 06:21:45 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Talks]]></category>

		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/03/07/jruby-enterprise-20-slides/</guid>
		<description><![CDATA[Here's the slides from  “JRuby: Enterprise 2.0″ from our recent talks at Sun Tech Day and the ACS Web Technologies SIG.
]]></description>
			<content:encoded><![CDATA[<p>Here's the <a href='http://jamescrisp.org/wordpress/wp-content/uploads/2008/03/jruby-enterprise-20.pdf' title='"JRuby: Enterprise 2.0" Slides'>slides from  “JRuby: Enterprise 2.0″</a> from our <a href="http://jamescrisp.org/2008/02/23/jruby-enterprise-20-presentations/">recent talks</a> at Sun Tech Day and the ACS Web Technologies SIG.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/03/07/jruby-enterprise-20-slides/feed/</wfw:commentRss>
		</item>
		<item>
		<title>“JRuby: Enterprise 2.0″ Presentations</title>
		<link>http://jamescrisp.org/2008/02/23/jruby-enterprise-20-presentations/</link>
		<comments>http://jamescrisp.org/2008/02/23/jruby-enterprise-20-presentations/#comments</comments>
		<pubDate>Sat, 23 Feb 2008 01:27:57 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2008/02/23/jruby-enterprise-20-presentations/</guid>
		<description><![CDATA[Josh Price and I will be co-presenting at the Melbourne Sun Tech Day and the Sydney ACS Web Technologies SIG. Here's the low down:

JRuby: Enterprise 2.0
There's a lot of buzz around JRuby in both the Java and Ruby communities, for good reason. This talk will give you a whirlwind introduction to JRuby. We'll show you [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.workingwithrails.com/person/8781-josh-price">Josh Price</a> and I will be co-presenting at the Melbourne Sun Tech Day and the Sydney ACS Web Technologies SIG. Here's the low down:</p>
<div style="border-left: 2px solid grey; margin-left: 2px; padding-left: 5px;">
<b>JRuby: Enterprise 2.0</b><br />
There's a lot of buzz around JRuby in both the Java and Ruby communities, for good reason. This talk will give you a whirlwind introduction to JRuby. We'll show you why JRuby is regarded as such a powerful and dynamic development platform. We'll also suggest where to use JRuby in product development and the enterprise and how to leverage your existing Java investments.<br />
There will be sample applications, live demos and not many slides.</p>
<p><i>Sun Tech Day Melbourne</i><br />
4 March 2008, 2:30pm<br />
<a href="http://au.sun.com/sunnews/events/2008/techdays/agenda_melbourne.jsp">More info on Sun site...</a></p>
<p><i>ACS Web Technologies SIG Sydney</i><br />
5 March 2008, 6:15pm<br />
<a href="http://acs.org.au/index.cfm?action=event&#038;area=9001&#038;temID=eventdetails&#038;eveID=10098821082566">More info on ACS site...</a>
</div>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/02/23/jruby-enterprise-20-presentations/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Practical JRuby on Rails (Web 2.0 Projects) by Ola Bini</title>
		<link>http://jamescrisp.org/2007/12/16/practical-jruby-on-rails-web-20-projects-by-ola-bini/</link>
		<comments>http://jamescrisp.org/2007/12/16/practical-jruby-on-rails-web-20-projects-by-ola-bini/#comments</comments>
		<pubDate>Sun, 16 Dec 2007 04:39:37 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/12/16/practical-jruby-on-rails-web-20-projects-by-ola-bini/</guid>
		<description><![CDATA[The fine folk at Apress sent me a copy of Ola Bini's new book to review. The full title is "Practical JRuby on Rails Web 2.0 Projects - Bringing Ruby On Rails to the Java Platform". Overall, it was a good read, and extremely valuable to anyone who is developing in JRuby. JRuby information and [...]]]></description>
			<content:encoded><![CDATA[<p>The fine folk at <a href="http://www.apress.com/">Apress</a> sent me a copy of <a href="http://ola-bini.blogspot.com/">Ola Bini</a>'s new book to review. The full title is <a href="http://www.amazon.com/Practical-JRuby-Rails-Web-Projects/dp/1590598814">"Practical JRuby on Rails Web 2.0 Projects - Bringing Ruby On Rails to the Java Platform"</a>. Overall, it was a good read, and extremely valuable to anyone who is developing in JRuby. JRuby information and documentation is scarce and most of the time, a Google trawl does not give you good results on a JRuby related query. Ola's is the first, and currently the only JRuby book available, and in my experience, the most valuable resource available to give you an all-round picture of JRuby capabilities and usage.</p>
<p><strong>Audience</strong><br />
Despite comments on the cover, I would suggest that this book is not ideal for people new to Ruby / Rails. Ola jumps in the deep end quite quickly, and being a talented Ruby programmer, makes use of lots of shorthand, procs, code blocks etc which would likely be hard to follow for someone new to Ruby. Although there is a section at the back called "Ruby for Java programmers", I think this would not be sufficient for somebody new to Ruby to understand all the code examples.</p>
<p>To get the most value out of the book, it would be good to have at least a basic understanding of Ruby and Rails (eg, having read <a href="http://www.amazon.com/Agile-Web-Development-Rails-2nd/dp/0977616630">Agile Web Development with Rails</a> or messed around with Ruby/Rails a bit) and a basic understanding of Java syntax, deployment and Java EE.</p>
<p><strong>What's Covered?</strong><br />
The book is project based, so as to give context and useful examples of JRuby functionality. There are 4 projects:</p>
<ul>
<li>The Store (Shoplet) - a standard Rails app running under JRuby using Active Record JDBC.</li>
<li>Content management system - general Java integration and using Java libraries for content rendering.</li>
<li>Administration System - using EJBs, JMX and discussion of JRuby deployment options.</li>
<li>Library System - JRuby as the "glue that never sets". Using Java Web service frameworks and JMS from JRuby.</li>
</ul>
<p><strong>The Good</strong></p>
<ul>
<li>Teaches you how to do all those tricky bits which are half-Java and half-Ruby and can't be easily found online, such as converting between Ruby and Java types, including JAR files, implementing Java interfaces, etc</li>
<li>Clever and concise Ruby code - I picked up some Ruby tricks reading Ola's code.</li>
<li>Complex code snippets are generally well explained in text.</li>
<li>Useful tips on when to use Java libraries and when to use Ruby ones.</li>
<li>Generally good and interesting example projects which justified the use of JRuby and the techniques shown in the book.</li>
<li>Helpful discussion of JDBC and database connectivity options for JRuby.</li>
<li>Nice overview of the many JRuby deployment options.</li>
<li>Helpful "sidebars" about Java Enterprise Edition technologies.</li>
<li>Covers the strong areas of JRuby well - web applications and system integration.</li>
<li>Appendices provide useful reference information.</li>
<li>Nice section at the end on how you can get involved in JRuby.</li>
</ul>
<p><strong>The Less Good</strong></p>
<ul>
<li>Example views often contain table layouts, inline styles and other layout information that would be better done in separate CSS files.</li>
<li>Variable names in code could be more descriptive. This would make example code easier to follow.</li>
<li>Occasional odd spelling like "sur_name" and use of deprecated Rails features, such as "start_form_tag" (to be fair though, Rails API does change very quickly).</li>
<li>The title suggests that the book is about Web 2.0. There is a little token AJAX, and I suppose a content management system is a bit Web 2.0, but overall, buy the book if you want to know about JRuby, not Web 2.0.</li>
<li>Although REST is only mentioned briefly in a little sidebar, and not a focus of the book, I found the description of REST and CRUD a bit misleading, especially when considering <a href="http://www.elharo.com/blog/software-development/web-development/2005/12/08/post-vs-put/">PUT vs POST</a>.</li>
<li>The discussion of JRuby deployment provides a good overview, but more in depth discussion of major options (eg, GoldSpike), and production configurations would be great.</li>
</ul>
<p><strong>Conclusion</strong><br />
As the best and only JRuby reference, I'd highly recommend you buy a copy if you are working in, or planning to work in JRuby. The book will help you to write JRuby applications which make good use of Ruby, Rails, Java libraries and Java Enterprise Edition features.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/12/16/practical-jruby-on-rails-web-20-projects-by-ola-bini/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Treo 650 incompatible with Optus Postpaid SIMs</title>
		<link>http://jamescrisp.org/2007/12/13/treo-650-incompatible-with-optus-postpaid-sims/</link>
		<comments>http://jamescrisp.org/2007/12/13/treo-650-incompatible-with-optus-postpaid-sims/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 09:19:09 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/12/13/treo-650-incompatible-with-optus-postpaid-sims/</guid>
		<description><![CDATA[Over the last 6 months, my old Treo 600 touch screen was dying. Cleaning and re-seating helped for a while, but eventually, the touch screen stopped working. As the Treo 680 barely improves on the Treo 650, and costs a lot more, I bought a new-ish Treo 650 on eBay. All went well until I [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last 6 months, my old Treo 600 touch screen was dying. <a href="http://jamescrisp.org/2007/05/18/fixing-a-palm-treos-digitizer-touch-screen/">Cleaning and re-seating</a> helped for a while, but eventually, the touch screen stopped working. As the Treo 680 barely improves on the Treo 650, and costs a lot more, I bought a new-ish Treo 650 on eBay. All went well until I tried to send SMSes using my Optus SIM. No luck - I got an error 4027 every time I tried to send a SMS, although voice and GPRS worked fine. </p>
<p>First attempt at a solution was to set the Message Centre Number in the phone. Strangely, the Message Centre number (configured though the SMS app) was always empty, and when I tried to set it to the correct number for Optus, the value wouldn't stick past a phone reset. </p>
<p>Thanks to Google, I found the <a href="http://sjmcloughlin.proboards37.com/index.cgi?action=display&#038;board=general&#038;thread=1171618891&#038;page=1#1172137191">outline of a solution on a message board</a>.</p>
<p>In summary, the Treo 650 (unlike the Treo 600) is not compatible with Optus's standard post-paid/plan SIMs used in Australia. However, it is compatible with the Optus pre-paid SIMs. If you have a Treo 650, and a post-paid/plan SIM, you can buy yourself a new pre-paid SIM for $4 from your local Optus store, then ring the Optus call centre to have them do a "SIM replacement" to move your account and number to the new SIM. This solves the problem within minutes of the "SIM replacement".</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/12/13/treo-650-incompatible-with-optus-postpaid-sims/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Automating MySQL Database Backups</title>
		<link>http://jamescrisp.org/2007/12/09/automating-mysql-database-backups/</link>
		<comments>http://jamescrisp.org/2007/12/09/automating-mysql-database-backups/#comments</comments>
		<pubDate>Sun, 09 Dec 2007 01:37:15 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/12/09/automating-mysql-database-backups/</guid>
		<description><![CDATA[Great, so you've got your web application up and running on some server somewhere, and  thousands of users are hard at work entering their valuable data into your application, and thence to a MySQL database. Now people depend on your system to keep their data safe. What are you going to do about it?
The [...]]]></description>
			<content:encoded><![CDATA[<p>Great, so you've got your web application up and running on some server somewhere, and  thousands of users are hard at work entering their valuable data into your application, and thence to a MySQL database. Now people depend on your system to keep their data safe. What are you going to do about it?</p>
<p>The approach I've taken is to run a backup script on a cron job, which dumps data from the database a few times a daily, compresses it, and emails it off to my GMail account. All those GMail gigabytes have got to be good for something, right :-)?</p>
<p>I started writing a simple backup shell script using mysqldump, gzip and sendmail, but ran into problems on RailsPlayground as sendmail is not supported there. RailsPlayground suggested this <a href="http://worldcommunity.com/opensource/utilities/mysql_backup.txt">perl script for mysql backup</a> (<a href="http://jamescrisp.org/wordpress/wp-content/uploads/2007/12/mysql_backup.txt">mirrored on my server</a>). The script does pretty much what I was looking for, and also supports skipping tables (useful for ignoring things like session tables, which, for my app, are not really worth backing up).</p>
<p>A little more investigation revealed that the script wouldn't work out of the box, as RailsPlayground requires SMTP auth. The backup script is not hard to enhance to support SMTP auth. It can be done as follows:</p>
<p>In the configuration section of the file (around line 203), add 2 new variables:</p>
<pre>
$smtp_user           = "my username"
$smtp_password       = "my password"
</pre>
<p>Around line 1200, add in the AuthUser and AuthPass:</p>
<pre>
MIME::Lite->send("$send_method", "$mailprog_or_smtp_host", Timeout=>60,
            AuthUser=>$smtp_user, AuthPass=>$smtp_password);
</pre>
<p>As an aside, this script can also do backups via FTP.</p>
<p>Restore of mysql dump files is pretty easy. You just use the standard client:</p>
<pre>
mysql -uMyUser -p MyDatabaseName < SqlDumpFile.sql
</pre>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/12/09/automating-mysql-database-backups/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Opera Browser - Lean and quick</title>
		<link>http://jamescrisp.org/2007/12/02/opera-browser-lean-and-quick/</link>
		<comments>http://jamescrisp.org/2007/12/02/opera-browser-lean-and-quick/#comments</comments>
		<pubDate>Sun, 02 Dec 2007 04:54:29 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/12/02/opera-browser-lean-and-quick/</guid>
		<description><![CDATA[I've been using Firefox since its inception, and its glorious introduction of tabbed browsing. However, every new update, Firefox seems to get ever slower, and use more memory and more processor. 
Finally, last week, after Firefox hung yet again using 100% of processor and over 300mb of memory, I decided to give Opera a go. [...]]]></description>
			<content:encoded><![CDATA[<p>I've been using <a href="http://www.mozilla.com/firefox/">Firefox</a> since its inception, and its glorious introduction of tabbed browsing. However, every new update, Firefox seems to get ever slower, and use more memory and more processor. </p>
<p>Finally, last week, after Firefox hung yet again using 100% of processor and over 300mb of memory, I decided to give <a href="http://www.opera.com/">Opera</a> a go. So far, I've been very satisfied. It was a small download, easy install and uses about 1/3 of the memory and significantly less processor than Firefox does, especially when you have many tabs open and leave the same instance of the browser running for several days. I've had one crash when setting up Adobe Acrobat preferences, but in general browsing, it is yet to break. Pages load faster, and rendering of HTML and CSS seems fine. The only problem I've had is with <a href="http://www.ihatelotusnotes.com/">Lotus Notes</a> Webmail saying Opera is "not supported" and not wanting to run.</p>
<p>So far, I've installed <a href="http://www.opera.com/">Opera</a> on older Windows and Mac boxes, and been very happy with the improved browsing experience. I still keep my Firefox handy though, mainly for its great web development plug-ins (<a href="http://www.getfirebug.com/">Firebug</a> and friends).</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/12/02/opera-browser-lean-and-quick/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hosting at Rails Playground, a review</title>
		<link>http://jamescrisp.org/2007/11/10/hosting-at-rails-playground-a-review/</link>
		<comments>http://jamescrisp.org/2007/11/10/hosting-at-rails-playground-a-review/#comments</comments>
		<pubDate>Sat, 10 Nov 2007 00:10:33 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/11/10/hosting-at-rails-playground-a-review/</guid>
		<description><![CDATA[I've been meaning to write about Rails Playground for a while. I currently use their level 2 developer hosting and I've been very happy with it. I host several domains and subdomains on my account. I run several rails apps (including my online wedding registry site, this blog (WordPress) and a wiki (moin) on it. [...]]]></description>
			<content:encoded><![CDATA[<p>I've been meaning to write about <a href="http://railsplayground.com">Rails Playground</a> for a while. I currently use their <a href="http://www.railsplayground.com/plans/developer/index.html">level 2 developer hosting</a> and I've been very happy with it. I host several domains and subdomains on my account. I run several rails apps (including my <a href="http://yourweddingpresents.com">online wedding registry</a> site, this blog (WordPress) and a wiki (moin) on it. </p>
<p>You get shell access, sFTP and cPanel, MySQL, PostgreSQL and also unlimited subversion repositories. Another neat feature is that you get 2 mongrel instances included. You need to ask Rails Playground staff to set these up for you, but they are quite prompt and friendly. I did have some problems with Mongrel instances dying, but the Rails Playground staff added a cron job to restart them, and this has solved the issue. At currently $12/month (or $9/month if you pay for a year), it is quite economical hosting. </p>
<p>I'd highly recommend Rails Playground if you're a rails developer looking for hosting (with fcgi and mongrels) and subversion, and you don't want/need the flexibility/hassle/higher price of a virtual private server.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/11/10/hosting-at-rails-playground-a-review/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Wedding Registries for the Pommies</title>
		<link>http://jamescrisp.org/2007/10/20/wedding-registries-for-the-pommies/</link>
		<comments>http://jamescrisp.org/2007/10/20/wedding-registries-for-the-pommies/#comments</comments>
		<pubDate>Sat, 20 Oct 2007 01:20:57 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[YourWeddingPresents.com]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/10/20/wedding-registries-for-the-pommies/</guid>
		<description><![CDATA[Your Wedding Presents now shows all money amounts in pounds, if you say you are from the United Kingdom. God Save the Queen!
]]></description>
			<content:encoded><![CDATA[<p><a href="http://yourweddingpresents.com">Your Wedding Presents</a> now shows all money amounts in pounds, if you say you are from the United Kingdom. God Save the Queen!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/10/20/wedding-registries-for-the-pommies/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Delicious .NET - Slides &amp; Code</title>
		<link>http://jamescrisp.org/2007/10/04/delicious-net-slides-code/</link>
		<comments>http://jamescrisp.org/2007/10/04/delicious-net-slides-code/#comments</comments>
		<pubDate>Thu, 04 Oct 2007 04:47:07 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/10/04/delicious-net-slides-code/</guid>
		<description><![CDATA[Here's the slides and code from yesterday's "Delicious Dot Net" talk at ACS.


  Powerpoint Presentation


  Delicious Server Code


  Delicious Client Code (online and offline)


  Microsoft samples



]]></description>
			<content:encoded><![CDATA[<p>Here's the slides and code from yesterday's <a href="http://jamescrisp.org/2007/09/28/acs-talk-delicious-net-3rd-oct/">"Delicious Dot Net" talk at ACS</a>.</p>
<ul>
<li>
  <a href="/wordpress/wp-content/uploads/2007/10/DeliciousDotNet.ppt">Powerpoint Presentation</a>
</li>
<li>
  <a href="/wordpress/wp-content/uploads/2007/10/DeliciousServer.zip">Delicious Server Code</a>
</li>
<li>
  <a href="/wordpress/wp-content/uploads/2007/10/DeliciousClient.zip">Delicious Client Code (online and offline)</a>
</li>
<li>
  <a href="/wordpress/wp-content/uploads/2007/10/MicrosoftSamples.zip">Microsoft samples</a>
</li>
</ul>
<p><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/10/04/delicious-net-slides-code/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ACS Talk - “Delicious .NET” - 3rd Oct</title>
		<link>http://jamescrisp.org/2007/09/28/acs-talk-delicious-net-3rd-oct/</link>
		<comments>http://jamescrisp.org/2007/09/28/acs-talk-delicious-net-3rd-oct/#comments</comments>
		<pubDate>Fri, 28 Sep 2007 13:41:38 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/09/28/acs-talk-delicious-net-3rd-oct/</guid>
		<description><![CDATA[I'll be giving a talk at an ACS event after work on Wed next week (3rd October). Here's the blurb:
A tasty take on WPF, WCF, LINQ and O-R Mapping
An exploration of some of the freshest, tastiest and most powerful features in .NET 3.5 through implementing a useful application.
You'll take away an understanding of what's in [...]]]></description>
			<content:encoded><![CDATA[<p>I'll be giving a talk at an ACS event after work on Wed next week (3rd October). Here's the blurb:</p>
<p><b>A tasty take on WPF, WCF, LINQ and O-R Mapping</b></p>
<p>An exploration of some of the freshest, tastiest and most powerful features in .NET 3.5 through implementing a useful application.<br />
You'll take away an understanding of what's in .NET 3.5 and how to build online and offline applications with the new technology stack supported by Visual Studio 2008 (Orcas Beta 2). </p>
<p><b>Location</b><br />
Norman Selfe Room,<br />
Level 3,<br />
280 Pitt St Sydney (Sydney Mechanics School of Arts)</p>
<p><b>Time</b><br />
6:15pm, 3rd October 2007</p>
<p>For more info or to register, please visit the <a href="http://acs.org.au/index.cfm?action=event&#038;area=9001&#038;temID=eventdetails&#038;eveID=10082197413786">ACS site</a>.</p>
<p>Hope you can come <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/09/28/acs-talk-delicious-net-3rd-oct/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Reflexil, cute code injection for C#</title>
		<link>http://jamescrisp.org/2007/09/27/reflexil-cute-code-injection-for-c/</link>
		<comments>http://jamescrisp.org/2007/09/27/reflexil-cute-code-injection-for-c/#comments</comments>
		<pubDate>Thu, 27 Sep 2007 07:20:42 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/09/27/reflexil-cute-code-injection-for-c/</guid>
		<description><![CDATA[While catching up on my favourite blogs, I came across Reflexil on Fabrice's blog. Reflexil is able to do C# code injection into existing assemblies and save the resulting assembly. I haven't given it a go yet, but it looks like a really neat tool. The legal implications may mean it is only useful for [...]]]></description>
			<content:encoded><![CDATA[<p>While catching up on my favourite blogs, I came across <a href="http://sebastien.lebreton.free.fr/reflexil/">Reflexil</a> on <a href="http://weblogs.asp.net/fmarguerie/archive/2007/09/05/Reflexil-csharp-code-injection-in-assemblies.aspx">Fabrice's blog</a>. Reflexil is able to do C# code injection into existing assemblies and save the resulting assembly. I haven't given it a go yet, but it looks like a really neat tool. The legal implications may mean it is only useful for emergency patching or debugging however...</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/09/27/reflexil-cute-code-injection-for-c/feed/</wfw:commentRss>
		</item>
		<item>
		<title>WebJam this Saturday Night</title>
		<link>http://jamescrisp.org/2007/09/26/webjam-this-saturday-night/</link>
		<comments>http://jamescrisp.org/2007/09/26/webjam-this-saturday-night/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 11:23:35 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Talks]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/09/26/webjam-this-saturday-night/</guid>
		<description><![CDATA[WebJam is usually quite fun. The premise is that a large group of people meet in a pub, have a few drinks (often sponsored by some generous company) and see quite a number of presenters who have 3 minutes each to show off cool, web-related stuff they've done recently. The next one is this Saturday. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://webjam.com.au/">WebJam</a> is usually quite fun. The premise is that a large group of people meet in a pub, have a few drinks (often sponsored by some generous company) and see quite a number of presenters who have 3 minutes each to show off cool, web-related stuff they've done recently. The next one is this Saturday. Details as follows:</p>
<p><b>Place:</b> Bar Broadway (opposite UTS)<br />
<b>Date:</b> 29 Sept 07<br />
<b>Time:</b> 6pm</b></p>
<p>I'm planning to go, and also to give a 3 minute presentation on my new <a href="http://yourweddingpresents.com">free wedding registry site</a>.</p>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/09/26/webjam-this-saturday-night/feed/</wfw:commentRss>
		</item>
		<item>
		<title>JRuby on Rails with GoldSpike - Scaling for more users</title>
		<link>http://jamescrisp.org/2007/09/26/jruby-on-rails-with-goldspike-scaling-for-more-users/</link>
		<comments>http://jamescrisp.org/2007/09/26/jruby-on-rails-with-goldspike-scaling-for-more-users/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 07:55:41 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/09/26/jruby-on-rails-with-goldspike-scaling-for-more-users/</guid>
		<description><![CDATA[The default configuration for running JRuby on Rails using GoldSpike only allows 4 instances of the JRuby runtime. This means that if there are more than 4 simultaneous requests from clients, the web server will respond with a server overloaded error. The easiest way to see what's going on is to take a look at [...]]]></description>
			<content:encoded><![CDATA[<p>The default configuration for running JRuby on Rails using GoldSpike only allows 4 instances of the JRuby runtime. This means that if there are more than 4 simultaneous requests from clients, the web server will respond with a server overloaded error. The easiest way to see what's going on is to take a look at the 'createObjectPool' method of <a href="http://www.koders.com/java/fid184901B6B416637DFBFB0F3C30F88647642D988E.aspx">RailsServlet</a>.</p>
<p>With a dedicated production server with 1gig of memory, it is possible to allow a lot more JRuby runtimes, and hence allow for more simultaneous users. A little load testing on a fairly small app suggested that 20 instances of JRuby runtime would fit comfortably under the 1gig ceiling and not overload the processor.</p>
<p>An easy way to change the max number of runtimes is to edit 'web.xml' in a JRuby application's WEB-INF directory. Parameter is set as follows:</p>
<pre>
  &lt;context-param&gt;
    &lt;param-name>jruby.pool.maxActive&lt;/param-name&gt;
    &lt;param-value>20&lt;/param-value&gt;
  &lt;/context-param&gt;
</pre>
<p>It is also worth checking with the web server configuration to ensure that the web server allows more threads than the number of JRuby runtimes specified in 'web.xml'.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/09/26/jruby-on-rails-with-goldspike-scaling-for-more-users/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ScreenCasting</title>
		<link>http://jamescrisp.org/2007/09/16/screencasting/</link>
		<comments>http://jamescrisp.org/2007/09/16/screencasting/#comments</comments>
		<pubDate>Sun, 16 Sep 2007 02:08:23 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[YourWeddingPresents.com]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/09/16/screencasting/</guid>
		<description><![CDATA[After being inspired by the Rails screencast long ago, I thought it would be fun to make a screencast for my free wedding registry site. It takes a bit of work. 
I checked out a few different screencast recording packages and ended up going with CamStudio. It is a fairly basic product but free and [...]]]></description>
			<content:encoded><![CDATA[<p>After being inspired by the Rails screencast long ago, I thought it would be fun to make a screencast for my <a href="http://yourweddingpresents.com">free wedding registry site</a>. It takes a bit of work. </p>
<p>I checked out a few different screencast recording packages and ended up going with <a href="http://www.camstudio.org/">CamStudio</a>. It is a fairly basic product but free and good enough for my needs. It lets you choose a window to record and also lets you include an audio track. I think the easiest way to use it is by recording to AVI (very quick) and then converting to Flash SWF (slow), when you are happy with the movie. In terms of SWF settings, I found the best combination was 16 bit colour, Playback rate and Keyframe rate at 20 frames / second. It is also a good idea to set the 'Percent of movie to preload' to something like 15%, to get things rolling quickly for your viewers.</p>
<p>I'm reasonably happy with the resulting <a href="http://screencast.yourweddingpresents.com">wedding registry screencast</a>, although there is certainly room for improvement. CamStudio unfortunately doesn't let you set the look and feel of the playback controls, so they feel a bit out of place. When I get time, I might also split the <a href="http://screencast.yourweddingpresents.com">screencast</a> into two - one from the bridal couple's perspective, and one from a guest's perspective.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/09/16/screencasting/feed/</wfw:commentRss>
		</item>
		<item>
		<title>YourWeddingPresents.com (wedding registry site) now live!</title>
		<link>http://jamescrisp.org/2007/09/13/yourweddingpresentscom-wedding-registry-site-now-live/</link>
		<comments>http://jamescrisp.org/2007/09/13/yourweddingpresentscom-wedding-registry-site-now-live/#comments</comments>
		<pubDate>Thu, 13 Sep 2007 13:52:44 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[YourWeddingPresents.com]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/09/13/yourweddingpresentscom-wedding-registry-site-now-live/</guid>
		<description><![CDATA[I'm really pleased to announce that YourWeddingPresents.com (a free, independent, wedding registry site) is now live! 
When my sister was getting married, she had a lot of trouble finding a good free wedding registry that was not tied to any particular shop. I developed the wedding registry site to fill this gap, and also to [...]]]></description>
			<content:encoded><![CDATA[<p>I'm really pleased to announce that <a href="http://yourweddingpresents.com">YourWeddingPresents.com (a free, independent, wedding registry site)</a> is now live! </p>
<p>When my sister was getting married, she had a lot of trouble finding a good free wedding registry that was not tied to any particular shop. I developed the <a href="http://yourweddingpresents.com">wedding registry site</a> to fill this gap, and also to improve my web programming skills. I've tried to design <a href="http://yourweddingpresents.com">Your Wedding Presents</a> to be really quick to sign up and easy to use. <a href="/contact">Please tell me</a> if there are any problems with the site, or ways the site could be made better.</p>
<p>On the technical side, I developed <a href="http://yourweddingpresents.com">Your Wedding Presents</a> using <a href="http://rubyonrails.org">Ruby on Rails</a>. It is running on an Apache load-balanced Mongrel cluster and data is stored in MySQL. It is hosted on <a href="http://www.railsplayground.com/">Rails Playground</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/09/13/yourweddingpresentscom-wedding-registry-site-now-live/feed/</wfw:commentRss>
		</item>
		<item>
		<title>JRuby, Rails and Statics</title>
		<link>http://jamescrisp.org/2007/09/09/jruby-rails-and-statics/</link>
		<comments>http://jamescrisp.org/2007/09/09/jruby-rails-and-statics/#comments</comments>
		<pubDate>Sun, 09 Sep 2007 07:07:09 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/09/09/jruby-rails-and-statics/</guid>
		<description><![CDATA[Say you wanted to store some information across different calls to your JRuby/Rails application on the server side. You could use a database, or memcached. However, what if you just want to do something very simple like a basic cache, and you don't have a database for your application? Memcached seems like overkill, and would [...]]]></description>
			<content:encoded><![CDATA[<p>Say you wanted to store some information across different calls to your JRuby/Rails application on the server side. You could use a database, or memcached. However, what if you just want to do something very simple like a basic cache, and you don't have a database for your application? Memcached seems like overkill, and would complicate your deployment considerably. So, what about just using statics?</p>
<p>Well, you can't do it in Ruby, as the Rails integration servlet spawns multiple instances of the JRuby interpreter.</p>
<p>Ruby code in a page view:</p>
<pre>&lt;h1&gt;Ruby global number&lt;/h1&gt;
<% $i ||= 0 %>
<% $i += 1 %>
<%= $i %>

&lt;h1&gt;Ruby obj id&lt;/h1&gt;
<% $o ||= Object.new %>
<%= $o.object_id %>
</pre>
<p>Results between multiple refreshes of the page:</p>
<pre>Ruby global number
1
Ruby obj id
244 

Ruby global number
1
Ruby obj id
256 

Ruby global number
2
Ruby obj id
244 

Ruby global number
2
Ruby obj id
256
</pre>
<p>Our requests seem to be switching between two instances of the Ruby interpreter. </p>
<p>However, we <b>*can*</b> do it in Java. My clever, Java-literate colleagues explained that Java application servers and servlet containers use a single instance of the JVM, but have a class loader for each application. The class loader stores class information and static values. This means that within one application, the static values will be maintained between requests, but a different application on the same server will have its own set of unrelated static values (similar to AppDomains in .NET).</p>
<p>If we add a call to a static method in Java that increments an integer and returns it, our view looks like this:</p>
<pre>&lt;h1&gt;Ruby global number&lt;/h1&gt;
<% $i ||= 0 %>
<% $i += 1 %>
<%= $i %>

&lt;h1&gt;Ruby obj id&lt;/h1&gt;
<% $o ||= Object.new %>
<%= $o.object_id %>

&lt;h1&gt;Java incrementing static integer&lt;/h1&gt;
<%= TestClass.incrementAndReturnNumber() %>
</pre>
<p>Our results now look a lot more useful. The Java static integer is getting incremented each call to the view:</p>
<pre>
Ruby global number
1
Ruby obj id
244
Java number
1 

Ruby global number
1
Ruby obj id
256
Java number
2 

Ruby global number
2
Ruby obj id
244
Java number
3 

Ruby global number
2
Ruby obj id
256
Java number
4
</pre>
<p>From this little experiment, Java statics seem like a possible way to go for storing temporary data on the server side (eg, a cache implemented as a singleton) for JRuby / Rails. Another option may be to use the ServletContext from the JRuby Rails integration servlet - probably an area worth investigating.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/09/09/jruby-rails-and-statics/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Web Design and CSS, how hard can it be?</title>
		<link>http://jamescrisp.org/2007/09/02/web-design-and-css-how-hard-can-it-be/</link>
		<comments>http://jamescrisp.org/2007/09/02/web-design-and-css-how-hard-can-it-be/#comments</comments>
		<pubDate>Sun, 02 Sep 2007 12:24:18 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/09/02/web-design-and-css-how-hard-can-it-be/</guid>
		<description><![CDATA[So, audaciously, I decided to do the theme for my pet Rails project. How hard can CSS and Photoshop really be? Having made basic layouts and modified various themes, I thought my CSS skills were adequate, and Photoshop is, after all, just another Windows application.
With the help of my talented fiancee and flatmate, the Photoshop [...]]]></description>
			<content:encoded><![CDATA[<p>So, audaciously, I decided to do the theme for my pet Rails project. How hard can CSS and Photoshop really be? Having made basic layouts and modified various themes, I thought my CSS skills were adequate, and Photoshop is, after all, just another Windows application.</p>
<p>With the help of my talented <a href="http://ohsoosun.blogspot.com">fiancee</a> and <a href="http://www.johncassimatis.com/">flatmate</a>, the Photoshop side of things went fairly well for a banner image. Not too hard, find a good image and apply some layers, effects and text.</p>
<p>When time came to hit the CSS, I felt confident. Based on my vague trial and error understanding of floats etc, I managed to spend a fair bit of time messing around, painfully, slowly getting a good layout in Firefox, only to be frustrated by an awful rendition in Internet Explorer. Then trying to make a compromise layout between the two that looked reasonable in both, only to have a slight change throw everything into disarray. Repeat ad nauseum. </p>
<p>Clearly, I my confidence was misplaced, and my CSS skills sucked. Time to actually learn something. I turned to my yet un-opened copy of <a href="http://www.csswebdevelopment.com/">"Beginning CSS Web Development - From Novice to Professional"</a> by Simon Collison, recommended by a ThoughtWorks buddy, <a href="http://www.thoughtworks.com/who-we-are/our-people/profiles/Oliver,+Warren.html">Warren</a>. I read it pretty much cover to cover on Saturday. It was quite a good read, practical with useful examples and a light tone. Lots of good stuff within:</p>
<ul>
<li>Clear explanation of the basics</li>
<li>Coverage of different browsers</li>
<li>Some insight into a web designer's mind</li>
<li>A number of useful page layouts</li>
<li>Different options for form layouts</li>
<li>Some advanced CSS tricks</li>
<li>A nice worked example of cutting up a Photoshop mock-up and turning it into image slices, CSS and HTML.</li>
</ul>
<p>Overall, the book was pretty much exactly what I needed to get back on track and bring my misbehaving CSS under control.</p>
<p>Here's a few things I learnt that solved some of the most pressing woes I was having with CSS:</p>
<ul>
<li>Margins collapse into each other. Ie, if you have two elements next to each other and each has a 10px margin, the total distance between the two will only be 10px. Adding 1px of padding will mean the borders of the two elements don't touch and hence won't collapse</li>
<li>Generally avoid padding on fixed width elements. Instead, wrap them in another element such as a div, and put the padding on it. That way, you avoid needing to do any hacks for the broken box model in older versions of IE.</li>
<li>You can put an ID on each pages' BODY, and that way, you can easily target elements on individual pages using their body's ID.</li>
<li>Often a good way of doing layout with floats is to keep the document as much using the normal flow layout, and then put in appropriate margins or padding to make space for floats, rather than floating the whole document.</li>
<li>The order of values in short declarations like 'margin: 1px 2px 3px 4px;' is top, right, bottom, left.</li>
<li>It is a good idea to stick to the limited set of web-safe fonts, and also use a number of fallbacks for font family to cover all viewers.</li>
</ul>
<p>My app's theme is not finished yet, but CSS has now become more a pleasure than a frustration.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/09/02/web-design-and-css-how-hard-can-it-be/feed/</wfw:commentRss>
		</item>
		<item>
		<title>BarCamp Sydney this Saturday</title>
		<link>http://jamescrisp.org/2007/08/22/barcamp-sydney-this-saturday/</link>
		<comments>http://jamescrisp.org/2007/08/22/barcamp-sydney-this-saturday/#comments</comments>
		<pubDate>Wed, 22 Aug 2007 12:09:05 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/08/22/barcamp-sydney-this-saturday/</guid>
		<description><![CDATA[It is BarCamp in Sydney this Saturday. I haven't been to one of these unconference style events before, but I've heard good things about it from my colleagues. I'm quite excited to go along and see what it is like. 
If you're in Sydney and interested in stopping by, details are as follows:
When: Sat 25th [...]]]></description>
			<content:encoded><![CDATA[<p>It is <a href="http://barcampsydney.org/">BarCamp in Sydney</a> this Saturday. I haven't been to one of these unconference style events before, but I've heard good things about it from my colleagues. I'm quite excited to go along and see what it is like. </p>
<p>If you're in Sydney and interested in stopping by, details are as follows:</p>
<p><b>When:</b> Sat 25th August 2007 from about 9am<br />
<b>Where:</b> University of Technology, Sydney (Jones St entrance)<br />
<a href="http://barcampsydney.org/?page_id=4">More details...</a></p>
<p>One of the novel aspects of BarCamp is that all participants are encouraged to present or start a discussion around something that interests them. For my part, depending on what people are interested in, I was thinking of one of the following:</p>
<ul>
<li>new stuff in the .net space (C# 3.0, .NET 3.5, LINQ, WPF, WCF, etc) and showing some demos</li>
<li>giving a bit of a Ruby/JRuby introduction with help from <a href="http://ola-bini.blogspot.com/2007/08/my-presentation-from-javabin.html">Ola's  JavaBin slides</a></li>
<li>or, if people are keen, a discussion around JRuby vs C# 3 vs Java vs ?? and their stacks for different situations and problems</li>
<ul>
<p>By the way, the conference is free, and it is not too late to sign up <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /><br />
Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/08/22/barcamp-sydney-this-saturday/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Slides from ‘Learning to live with the static-typing fascist and the dynamic-typing fan-boy in your enterprise…’</title>
		<link>http://jamescrisp.org/2007/08/15/slides-from-learning-to-live-with-the-static-typing-fascist-and-the-dynamic-typing-fan-boy-in-your-enterprise%e2%80%a6/</link>
		<comments>http://jamescrisp.org/2007/08/15/slides-from-learning-to-live-with-the-static-typing-fascist-and-the-dynamic-typing-fan-boy-in-your-enterprise%e2%80%a6/#comments</comments>
		<pubDate>Wed, 15 Aug 2007 02:03:13 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/08/15/slides-from-learning-to-live-with-the-static-typing-fascist-and-the-dynamic-typing-fan-boy-in-your-enterprise%e2%80%a6/</guid>
		<description><![CDATA[Here's the slides from Jim's and my recent presentation at Tech Ed 07 on the Gold Coast and in Auckland:
LearningToLiveWithTheStaticTypingFascistAndTheDynamicTypingFanboy-TechEd07.pptx  (Powerpoint 2007)
LearningToLiveWithTheStaticTypingFascistAndTheDynamicTypingFanboy-TechEd07.ppt (Powerpoint 2003)
You may also be interested in having a read of the abstract.
]]></description>
			<content:encoded><![CDATA[<p>Here's the slides from <a href="http://jim.webber.name">Jim</a>'s and my recent presentation at Tech Ed 07 on the Gold Coast and in Auckland:</p>
<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2007/08/LearningToLiveWithTheStaticTypingFascistAndTheDynamicTypingFanboy-TechEd07.pptx' title='LearningToLiveWithTheStaticTypingFascistAndTheDynamicTypingFanboy-TechEd07.ptx'>LearningToLiveWithTheStaticTypingFascistAndTheDynamicTypingFanboy-TechEd07.pptx  (Powerpoint 2007)</a></p>
<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2007/08/LearningToLiveWithTheStaticTypingFascistAndTheDynamicTypingFanboy-TechEd07.ppt' title='LearningToLiveWithTheStaticTypingFascistAndTheDynamicTypingFanboy-TechEd07.ppt'>LearningToLiveWithTheStaticTypingFascistAndTheDynamicTypingFanboy-TechEd07.ppt (Powerpoint 2003)</a></p>
<p>You may also be interested in having a read of the <a href="http://jamescrisp.org/2007/08/02/tech-ed-talks/">abstract</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/08/15/slides-from-learning-to-live-with-the-static-typing-fascist-and-the-dynamic-typing-fan-boy-in-your-enterprise%e2%80%a6/feed/</wfw:commentRss>
		</item>
		<item>
		<title>TechEd 07 - Some interesting snippets</title>
		<link>http://jamescrisp.org/2007/08/14/teched-07-some-interesting-snippets/</link>
		<comments>http://jamescrisp.org/2007/08/14/teched-07-some-interesting-snippets/#comments</comments>
		<pubDate>Mon, 13 Aug 2007 22:06:11 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/08/14/teched-07-some-interesting-snippets/</guid>
		<description><![CDATA[Silverlight

Silverlight runs on MAC and PC.
There is now a CLR for the Mac.
Microsoft is not currently planning to provide Silverlight for any unix platform (although there is MoonLight).
Silverlight 1.0 is basically a media player. It has hooks for javascript etc and some might say it has similar functionality to the Flash movie player.
Silverlight 1.1 has [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Silverlight</strong></p>
<ul>
<li>Silverlight runs on MAC and PC.</li>
<li>There is now a CLR for the Mac.</li>
<li>Microsoft is not currently planning to provide Silverlight for any unix platform (although there is MoonLight).</li>
<li>Silverlight 1.0 is basically a media player. It has hooks for javascript etc and some might say it has similar functionality to the Flash movie player.</li>
<li>Silverlight 1.1 has the real programming API. All further Silverlight references are to 1.1.</li>
<li>Silverlight will do a (currently undefined) simplified subset of WPF.</li>
<li>Silverlight gives acess to DOM in the browser.</li>
<li>Currently, the alpha allows 1mb local storage per page. In future, the storage is probably going to be shared across a domain rather than on a page by page basis.</li>
<li>Silverlight provides the capability to open a file on disk for read to allow for file uploads etc.</li>
<li>Interop between JavaScript and hosted Silverlight app is quite easy.</li>
<li>Silverlight looks a bit fiddly to set up, requiring javascript and sometimes xaml bootstrap - but being improved.</li>
</ul>
<p><strong>Software Factories</strong></p>
<ul>
<li>Allow solution and project structures to be auto-generated based on wizards.</li>
<li>Can provide code snippets and some (often template-based) code auto-generation.</li>
<li>Comes with documentation in help files and some context specific stuff.</li>
<li>Can include GUI designers that generate code.</li>
<li>People can develop their own domain specific factories.</li>
</ul>
<p><strong>DSLs</strong><br />
Currently, Microsoft's take on DSLs is GUI editors, not written language or code. At the Software Factories talk, a GUI tool in Visual Studio for drawing your business entities and relationships was billed as a DSL.</p>
<p><strong>Windows Workflow Foundation (WF)</strong></p>
<ul>
<li>Activity based with GUI designer for connecting and composing activities.</li>
<li>Custom activities and compositions can be developed and inherit from base classes.</li>
<li>Single threaded and mainly queue based, with some events sprinkled through.</li>
<li>Activities can reference data from other activities using a mechanism vaguely like data binding.</li>
<li>Hosted in the CLR, so can be part of a console app, ASP.NET, WinForms etc.</li>
<li>Handles pickling and reconstitution of long running activities.</li>
<li>Base Activity classes provide virtual hooks. Eg, 'Execute' for doing the work, 'Cancel', and 'Compensate' for handling rollback scenarios.
</ul>
<p><strong>New in the Enterprise Library 3.1</strong></p>
<ul>
<li>Validation Application Block: provides simple, attribute based property validation. Easy integration with standard ErrorProvider on WinForms and WebForms and WPF is possible. Looks ok but somewhat basic - don't think it supports warnings for example. It has GUI tool support and also capability to specify related objects which need to be validated.</li>
<li>Policy Injection Application Block: provides aspect oriented programming (AOP) style coding using attributes. All new AOP objects need to be created using the block's object factory. Looks useful - there is out of the box support for validation, caching and logging in AOP fashion.</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/08/14/teched-07-some-interesting-snippets/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tech Ed Talks</title>
		<link>http://jamescrisp.org/2007/08/02/tech-ed-talks/</link>
		<comments>http://jamescrisp.org/2007/08/02/tech-ed-talks/#comments</comments>
		<pubDate>Thu, 02 Aug 2007 06:37:18 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Talks]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2007/08/02/tech-ed-talks/</guid>
		<description><![CDATA[Jim Webber and I will be co-presenting at Tech Ed Australia and Tech Ed New Zealand this year. Here's the low down:
Learning to live with the static-typing fascist and the dynamic-typing fan-boy in your enterprise... 
Gold Coast
Thursday 9 Aug
5pm - 6:15pm
Auckland
Tuesday 14 Aug
2:20pm - 3:35pm
"What's best for your enterprise? Is it the 'glue that never [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jim.webber.name">Jim Webber</a> and I will be co-presenting at <a href="https://aunz.msteched.com/public/ausessions.aspx">Tech Ed Australia</a> and <a href="https://aunz.msteched.com/public/nzsessions.aspx">Tech Ed New Zealand</a> this year. Here's the low down:</p>
<div style="border-left: 2px solid grey; margin-left: 2px; padding-left: 5px;"><strong>Learning to live with the static-typing fascist and the dynamic-typing fan-boy in your enterprise... </strong></p>
<p><em>Gold Coast</em><br />
Thursday 9 Aug<br />
5pm - 6:15pm</p>
<p><em>Auckland</em><br />
Tuesday 14 Aug<br />
2:20pm - 3:35pm</p>
<p>"What's best for your enterprise? Is it the 'glue that never sets' and flexibility of dynamic languages like Ruby, or the tried and true, hard and fast rules and tool support of static languages like C# 3.0? Are there different trade-offs for green field development and integration?</p>
<p>And more importantly, which is best, the Mac or PC?</p>
<p>In a dynamic, and combative presentation, Jim and James will let their alter-egos run amok and answer these questions from the perspective of a seasoned enterprise architect and a l33t hax0r. By the end of this session you will understand the interplays between the two personality types, have had a few laughs, and picked up a few tips on how to use both technology<br />
sets in harmony in your enterprise. "</p></div>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/08/02/tech-ed-talks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ultimate Laptop Protection</title>
		<link>http://jamescrisp.org/2007/07/24/ultimate-laptop-protection/</link>
		<comments>http://jamescrisp.org/2007/07/24/ultimate-laptop-protection/#comments</comments>
		<pubDate>Mon, 23 Jul 2007 19:55:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=65</guid>
		<description />
			<content:encoded><![CDATA[<p><a href="http://bp3.blogger.com/_TlhwVaDeyBE/RqXbg7dtCCI/AAAAAAAAAXc/o_DxH1PHsSg/s1600-h/IMG_2514.JPG""><br />
<img src="http://bp3.blogger.com/_TlhwVaDeyBE/RqXbg7dtCCI/AAAAAAAAAXc/o_DxH1PHsSg/s400/IMG_2514.JPG" style="clear: left; margin: 0px auto 10px; cursor: pointer; float: left" id="BLOGGER_PHOTO_ID_5090716312576788514" border="0" /></a><br />
<a href="http://bp0.blogger.com/_TlhwVaDeyBE/RqXbhLdtCDI/AAAAAAAAAXk/vUuEhSUuKV0/s1600-h/IMG_2516.JPG"><br />
<img src="http://bp0.blogger.com/_TlhwVaDeyBE/RqXbhLdtCDI/AAAAAAAAAXk/vUuEhSUuKV0/s400/IMG_2516.JPG" style="clear: both; margin: 0px auto 10px; display: block; text-align: left; cursor: pointer; float: left" id="BLOGGER_PHOTO_ID_5090716316871755826" border="0" /></a></p>
<p style="clear: both"> Better than money can buy. Made by my dad <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/07/24/ultimate-laptop-protection/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Consulting</title>
		<link>http://jamescrisp.org/2007/07/15/consulting/</link>
		<comments>http://jamescrisp.org/2007/07/15/consulting/#comments</comments>
		<pubDate>Sun, 15 Jul 2007 13:58:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=64</guid>
		<description><![CDATA[A present from my adorable fiancée 
]]></description>
			<content:encoded><![CDATA[<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_TlhwVaDeyBE/RpoorqYxdTI/AAAAAAAAAXU/cstBI9Tp2W8/s1600-h/consulting-sm.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_TlhwVaDeyBE/RpoorqYxdTI/AAAAAAAAAXU/cstBI9Tp2W8/s400/consulting-sm.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5087423459646076210" /></a><br />A present from my <a href="http://ohsoosun.blogspot.com">adorable fiancée</a> <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/07/15/consulting/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Adding a New Rails Project under Subversion</title>
		<link>http://jamescrisp.org/2007/07/01/adding-a-new-rails-project-under-subversion/</link>
		<comments>http://jamescrisp.org/2007/07/01/adding-a-new-rails-project-under-subversion/#comments</comments>
		<pubDate>Sun, 01 Jul 2007 23:21:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=63</guid>
		<description><![CDATA[I generally use Subversion for source control when given the choice. In day to day usage, I like to use Tortoise SVN as it gives you a GUI with tick boxes for files to check in. However, it's handy to use the command line tool for project setup and automation.
Often, there is a subversion repository [...]]]></description>
			<content:encoded><![CDATA[<p>I generally use <a href="http://subversion.tigris.org/">Subversion</a> for source control when given the choice. In day to day usage, I like to use <a href="http://tortoisesvn.tigris.org/">Tortoise SVN</a> as it gives you a GUI with tick boxes for files to check in. However, it's handy to use the command line tool for project setup and automation.</p>
<p>Often, there is a subversion repository already set up and running on another machine. In this situation, I generally:</p>
<ol>
<li>Check out the repository at the top level into a temporary directory through Tortoise, add a new directory ([appname]) for the new project, and check it in.</li>
<li>Generate the new rails app (rails [appname]).</li>
<li>Check out [appname] from the repository into the local directory [appname] which contains the Rails project.</li>
<li>Add and check in all files through Tortoise.</li>
<li>Run the following commands from the command line to remove logs and tmp from the repository:</li>
</ol>
<pre>svn remove log/*

svn commit -m "removing all log files from subversion"

svn propset svn:ignore "*.log" log/svn update log/

svn commit -m "Ignoring all files in /log/ ending in .log"

svn remove tmp/*

svn propset svn:ignore "*" tmp/

svn update tmp/svn 

svn commit -m "Ignoring all files in /tmp/"</pre>
<p>There's more Rails/Subversion info to be found on the <a href="http://wiki.rubyonrails.org/rails/pages/HowtoUseRailsWithSubversion">Rails wiki</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/07/01/adding-a-new-rails-project-under-subversion/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Castle Project - Rails for .NET</title>
		<link>http://jamescrisp.org/2007/06/12/the-castle-project-rails-for-net/</link>
		<comments>http://jamescrisp.org/2007/06/12/the-castle-project-rails-for-net/#comments</comments>
		<pubDate>Tue, 12 Jun 2007 13:26:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=61</guid>
		<description><![CDATA[The Castle Project is an interesting open source alternative to ASP.NET / ADO.NET. Among other things, the Castle Project provides a Rails-like development framework for .NET. It has an ActiveRecord implementation built on top of NHibernate, a very Rails-like MVC setup called MonoRail, and uses NVelocity for template style views. It's worth checking out. This [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.castleproject.org/">The Castle Project</a> is an interesting open source alternative to ASP.NET / ADO.NET. Among other things, the Castle Project provides a <a href="http://www.rubyonrails.org/">Rails</a>-like development framework for .NET. It has an ActiveRecord implementation built on top of <a href="http://www.nhibernate.org/">NHibernate</a>, a very Rails-like MVC setup called MonoRail, and uses <a href="http://nvelocity.sourceforge.net/">NVelocity</a> for template style views. It's worth checking out. This <a href="http://hammett.castleproject.org/wp-content/uploads/2007/01/mr%20formvalidation.html">screencast</a> gives a bit of an overview.</p>
<p>There's tough competition around the corner though, with <a href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx">Orcas already in beta</a>, providing XAML, LINQ and O-R mapping.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/06/12/the-castle-project-rails-for-net/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Is .NET or Java dying?</title>
		<link>http://jamescrisp.org/2007/06/05/is-net-or-java-dying/</link>
		<comments>http://jamescrisp.org/2007/06/05/is-net-or-java-dying/#comments</comments>
		<pubDate>Tue, 05 Jun 2007 09:52:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=60</guid>
		<description><![CDATA[Are C# and .NET losing ground as Martin Fowler suggests? Or is Java's market share dropping? What about Ruby? And what about the Australian market in particular?
Here's what I've been able to find.
Job Trends
Which technologies have the most demand for people?
From Indeed.com, which claims to search "millions of jobs from thousands of job sites", but [...]]]></description>
			<content:encoded><![CDATA[<p>Are C# and .NET losing ground as <a href="http://martinfowler.com/bliki/RubyMicrosoft.html">Martin Fowler</a> suggests? Or is <a href="http://www.businessweek.com/technology/content/dec2005/tc20051213_042973.htm">Java's market share dropping</a>? What about Ruby? And what about the Australian market in particular?</p>
<p>Here's what I've been able to find.</p>
<p><span style="font-weight: bold;">Job Trends</span><br />
Which technologies have the most demand for people?</p>
<p>From <a href="http://www.indeed.com/jobtrends?q=.net%2C+java%2C+c%23%2C+ruby&#038;l=">Indeed.com</a>, which claims to search "millions of jobs from thousands of job sites", but I suspect may have a USA focus:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_TlhwVaDeyBE/RmTGdLuuu0I/AAAAAAAAAW8/Z5uOqrnvNJk/s1600-h/indeed.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_TlhwVaDeyBE/RmTGdLuuu0I/AAAAAAAAAW8/Z5uOqrnvNJk/s400/indeed.png" alt="" id="BLOGGER_PHOTO_ID_5072397284993317698" border="0" /></a></p>
<p><a href="http://www.vision6.com.au/ch/dx8s7z/236720/f5785zrx3.pdf">"Best Talent Index May 2007"</a> from <a href="http://best-international.com.au/">Best People Solutions</a>  gives an Australian perspective:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_TlhwVaDeyBE/RmTpGruuu1I/AAAAAAAAAXE/OxDKaQ4KZfY/s1600-h/best.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_TlhwVaDeyBE/RmTpGruuu1I/AAAAAAAAAXE/OxDKaQ4KZfY/s400/best.JPG" alt="" id="BLOGGER_PHOTO_ID_5072435381353233234" border="0" /></a></p>
<p>Here's job counts from the (largest?) primarily Australian job search site <a href="http://www.seek.com.au/">Seek</a> on 5 June 2007, 3pm (today):</p>
<table class="ttable" bordercolordark="#003366" bordercolorlight="#c0c0c0" id="Table2" align="center" border="1">
<tr>
<td><b>Keyword(s)</b></td>
<td><b>Number of positions found</b></td>
</tr>
<tr>
<td>Java</td>
<td>3,414</td>
</tr>
<tr>
<td>".NET" or "dot net"</td>
<td>2,744</td>
</tr>
<tr>
<td>"c#" or "c sharp"</td>
<td>1,722</td>
</tr>
<tr>
<td>ruby</td>
<td>100</td>
</tr>
</table>
<p>As an aside, I remember doing a search on Seek for "ruby" about 6 months ago, and getting under 20 jobs mentioning it.</p>
<p><span style="font-weight: bold;">Search Engine Number of Hits</span></p>
<p>Extract from the <a href="http://www.tiobe.com/tiobe_index/index.htm">TIOBE Programming Community Index for June 2007</a>:</p>
<table width="80%" class="ttable" bordercolordark="#003366" bordercolorlight="#c0c0c0" id="Table2" align="center" border="1">
<tbody>
<tr>
<th align="center"> Position<br />
Jun 2007</th>
<th align="center" >Position<br />
Jun 2006</th>
<th align="center" >Delta in Position</th>
<th align="center" >Programming Language</th>
<th align="center" >Ratings<br />
Jun 2007</th>
<th align="center" >Delta<br />
Jun 2006</th>
<th align="center" >Status</th>
</tr>
<tr>
<td align="center">1</td>
<td align="center">1</td>
<td align="center"><img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /></td>
<td><a href="http://www.tiobe.com/tiobe_index/Java.html">Java</a></td>
<td align="center">20.025%</td>
<td align="center">-1.10%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">2</td>
<td align="center">2</td>
<td align="center"><img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /></td>
<td><a href="http://www.tiobe.com/tiobe_index/C.html">C</a></td>
<td align="center">15.967%</td>
<td align="center">-2.29%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">3</td>
<td align="center">3</td>
<td align="center"><img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /></td>
<td><a href="http://www.tiobe.com/tiobe_index/C__.html">C++</a></td>
<td align="center">11.118%</td>
<td align="center">+0.45%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">4</td>
<td align="center">4</td>
<td align="center"><img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /></td>
<td><a href="http://www.tiobe.com/tiobe_index/%28Visual%29_Basic.html">(Visual) Basic</a></td>
<td align="center">9.332%</td>
<td align="center">-0.85%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">5</td>
<td align="center">5</td>
<td align="center"><img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /></td>
<td><a href="http://www.tiobe.com/tiobe_index/PHP.html">PHP</a></td>
<td align="center">8.871%</td>
<td align="center">-0.72%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">6</td>
<td align="center">6</td>
<td align="center"><img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /></td>
<td><a href="http://www.tiobe.com/tiobe_index/Perl.html">Perl</a></td>
<td align="center">6.177%</td>
<td align="center">+0.17%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">7</td>
<td align="center">8</td>
<td align="center"> <img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /> </td>
<td><a href="http://www.tiobe.com/tiobe_index/C_.html">C#</a></td>
<td align="center">3.483%</td>
<td align="center">+0.25%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">8</td>
<td align="center">7</td>
<td align="center"> <img src="http://www.tiobe.com/tiobe_index/images/Down.gif" border="0" /> </td>
<td><a href="http://www.tiobe.com/tiobe_index/Python.html">Python</a></td>
<td align="center">3.161%</td>
<td align="center">-0.30%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">9</td>
<td align="center">10</td>
<td align="center"> <img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /> </td>
<td><a href="http://www.tiobe.com/tiobe_index/JavaScript.html">JavaScript</a></td>
<td align="center">2.616%</td>
<td align="center">+1.16%</td>
<td align="left">  A</td>
</tr>
<tr height="25">
<td align="center">10</td>
<td align="center">19</td>
<td align="center"> <img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /><img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /><img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /><img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /><img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /><img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /><img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /><img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /><img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /> </td>
<td><a href="http://www.tiobe.com/tiobe_index/Ruby.html">Ruby</a></td>
<td align="center">2.132%</td>
<td align="center">+1.65%</td>
<td align="left">  A</td>
</tr>
</tbody>
</table>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_TlhwVaDeyBE/RmTxsLuuu2I/AAAAAAAAAXM/Klu2QZtQmEw/s1600-h/tpci_trends.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_TlhwVaDeyBE/RmTxsLuuu2I/AAAAAAAAAXM/Klu2QZtQmEw/s400/tpci_trends.png" alt="" id="BLOGGER_PHOTO_ID_5072444821691349858" border="0" /></a><br />
I think this gives a good idea of web buzz, but suggest that most non-IT companies do not publish information about their projects and chosen technologies and languages on the web.</p>
<p><span style="font-weight: bold;">Conclusion</span><br />
The data collected suggests that:</p>
<ul>
<li>Both .NET and Java are major players in the job market with thousands of positions advertised, implying wide industry adoption of both.</li>
<li>Neither .NET nor Java seem to be undergoing any significant decline in jobs.
</li>
<li>Java has much more information about it on the internet, although .NET is slowing gaining ground and Java slowly losing it.
</li>
<li>Ruby is comparatively tiny but growing rapidly in terms of jobs and information on the internet.
</li>
</ul>
<p><span style="font-weight:bold;">Thanks</span><br />
Thanks to <a href="http://jchyip.blogspot.com/">Jason Yip</a> and <a href="http://binkysilhouette.blogspot.com/">Suzi Edwards</a> for their help finding/sourcing information.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/06/05/is-net-or-java-dying/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Can you spot the bug?</title>
		<link>http://jamescrisp.org/2007/05/20/can-you-spot-the-bug/</link>
		<comments>http://jamescrisp.org/2007/05/20/can-you-spot-the-bug/#comments</comments>
		<pubDate>Sun, 20 May 2007 07:04:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=59</guid>
		<description><![CDATA[In a model class which has 'quantity', 'quantity_already_taken' and 'quantity_requested' properties, I add the following:
def before_save
  quantity = 1 if quantity == 0
  if quantity + quantity_already_taken &#62; quantity_requested
  ......
Tests blow up everywhere with:
TypeError: nil can't be coerced into Fixnum   (on the line with the addition)
Why?
After a little more debugging, [...]]]></description>
			<content:encoded><![CDATA[<p>In a model class which has 'quantity', 'quantity_already_taken' and 'quantity_requested' properties, I add the following:</p>
<pre>def before_save
  quantity = 1 if quantity == 0
  if quantity + quantity_already_taken &gt; quantity_requested
  ......</pre>
<p>Tests blow up everywhere with:</p>
<pre>TypeError: nil can't be coerced into Fixnum   (on the line with the addition)</pre>
<p>Why?</p>
<p>After a little more debugging, it is clear that 'quantity' is nil. How could that happen?</p>
<p>The answer lies in the fact that Ruby requires an explicit self reference when using attribute writers (aka, property setters) within the class itself. This feels clunky to me, but for your information, here's a <a href="http://www.rubyfleebie.com/use-self-explicitly/">rationalisation of the explicit self requirement</a>.</p>
<p>So, in case you're wondering, what happened above is that the 'if' line created a nil local variable called 'quantity'! This local variable then had higher scope precedence than the class attribute with the same name. The addition line was then using the local 'quantity' rather than the class attribute and hence failed with the nil error.</p>
<p>All fixed by explicity referencing self:</p>
<pre>def before_save
  self.quantity = 1 if (quantity == 0)
  if quantity + quantity_already_taken &gt; quantity_requested
  ......</pre>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/05/20/can-you-spot-the-bug/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fixing a Palm Treo’s Digitizer (Touch Screen)</title>
		<link>http://jamescrisp.org/2007/05/18/fixing-a-palm-treos-digitizer-touch-screen/</link>
		<comments>http://jamescrisp.org/2007/05/18/fixing-a-palm-treos-digitizer-touch-screen/#comments</comments>
		<pubDate>Fri, 18 May 2007 12:07:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=58</guid>
		<description><![CDATA[Let me tell you a sad tale. One day, out of the blue, the digitizer on my palm started to drift. Every hour, it got worse. This meant that when you tried to click a button like 'Add' the Palm thought you clicked 'Delete' - no fun at all! It was possible to temporarily improve [...]]]></description>
			<content:encoded><![CDATA[<p>Let me tell you a sad tale. One day, out of the blue, the digitizer on my palm started to drift. Every hour, it got worse. This meant that when you tried to click a button like 'Add' the Palm thought you clicked 'Delete' - no fun at all! It was possible to temporarily improve the situation by running the re-calibration program built into the system, but within a few hours, where you clicked again had very little relation to where the Palm thought you had clicked. After about a week, it was not possible to run the re-calibration program, as the digitizer was so far out (program just looped forever so I had to reboot the Palm). I discovered that there are actually keyboard shortcuts for just about everything, and that the 4-way <span class="blsp-spelling-error" id="SPELLING_ERROR_0">nav</span> button gets you most places, so the device wasn't a total write off. However, it was slow and cumbersome to use.</p>
<p>Now, one month later, I'm sure you'll be thrilled to know that things are better, the sorry tale has had a happy ending (touch wood!). Much googling led to many suggested approaches to fixing the problem including:
<ul>
<li>Various auto-calibration programs (<span class="blsp-spelling-error" id="SPELLING_ERROR_1">AutoDigi</span>, <span class="blsp-spelling-error" id="SPELLING_ERROR_2">DigiFix</span>, etc).</li>
<li>Running paper around the screen under the casing to remove gunk.</li>
<li>Cleaning the insides by putting a vacuum cleaner to all openings.</li>
</ul>
<p>However, all of these approaches ended with disappointment and no noticeable improvement.</p>
<p>Finally, near buying myself a new device (aside: it is a shame that Palm has not managed to produce a device significantly better than my several year old <span class="blsp-spelling-error" id="SPELLING_ERROR_3">Treo</span> 600), I came across a <a href="http://www.pdaparts.com/">site</a> selling replacement <span class="blsp-spelling-error" id="SPELLING_ERROR_4">Treo</span> 600 digitizer/screen modules. They kindly provide a very useful <a href="http://www.youtube.com/v/a5LQKzMi9pI">movie</a> on pulling your <span class="blsp-spelling-error" id="SPELLING_ERROR_5">Treo</span> apart to help you replace your digitizer/screen module. With little to lose, I decided to open up the case of my <span class="blsp-spelling-error" id="SPELLING_ERROR_6">Treo</span> and see if there was anything I could fix.</p>
<p>Following the instructions in the movie was not too difficult. I didn't have a small star <span class="blsp-spelling-error" id="SPELLING_ERROR_7">alan</span> key myself (required for opening the case), but I borrowed one from my dear dad, who has an amazing tool collection. Also, lacking a plastic case opening tool, I used a butter knife - this worked OK, but did damage the plastic of the case a little. If you have something made from thin and strong plastic, like the case opener in the movie, it would be a better tool for the job. I had a great time pulling everything apart and finally had all the components spread out before me. I cleaned the screen carefully (there was a fair bit of <span class="blsp-spelling-error" id="SPELLING_ERROR_8">grot</span> around the edges), fixed the buckled taping on the side of the screen, and put everything back together, carefully re-seating the various cables.</p>
<p>And now, almost a month later, the digitizer still seems to be working fine! Hurrah! So if you are contemplating what to do about your Palm's broken or drifting digitizer, I recommend pull it apart, clean it all and re-seat cables and then hope for the best!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/05/18/fixing-a-palm-treos-digitizer-touch-screen/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Experience of an International Amazon Virgin</title>
		<link>http://jamescrisp.org/2007/04/18/experience-of-an-international-amazon-virgin/</link>
		<comments>http://jamescrisp.org/2007/04/18/experience-of-an-international-amazon-virgin/#comments</comments>
		<pubDate>Thu, 19 Apr 2007 00:02:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=57</guid>
		<description><![CDATA[Recently I ordered 12 books from Amazon. It was my first time.
The process started really well - quite easy and pleasant to find the books I was after. Not to mention that amazing range and the great option of getting cheaper second hand books. Adding to the shopping cart was also a breeze.
I was pretty [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I ordered 12 books from Amazon. It was my first time.</p>
<p>The process started really well - quite easy and pleasant to find the books I was after. Not to mention that amazing range and the great option of getting cheaper second hand books. Adding to the shopping cart was also a breeze.</p>
<p>I was pretty impressed, good prices, nice process. But then the honeymoon was over. Time to check out - stream of consciousness. First, I need to enter address details. Fine, as expected. Then I get a message (from memory) "There is a slight problem with your order. Some of the books you have chosen cannot be shipped to your address. Change your delivery address or change the quantity to 0 on these books.". Not happy! One third of my books (second hand ones) cannot be sent. That means I need to cancel the check out process, remove 4 books from my cart and then try and find the same books from other more expensive suppliers which can be shipped international. So I try again, adding the same book from multiple suppliers to my cart, in the hope of finding one which can deliver to Australia. Then it's back to the checkout process again.. Problem - I missed one book and have to cancel the process and go back to basket process again. Great, all books are OK, finally time to complete the order. So I get to review my order, and it says at the top something like "With an Amazon credit card, this order would be $324 rather than $368". No other total including postage is provided. So is my order $368? Maybe? Further screens finally confirm that this is the case. Nowhere is it possible to see how much postage is per book - you have to work it out yourself doing best guesses and following the Amazon formula. Maybe it would have been better to get a new book rather than a second hand book, as second hand books have twice the postage charge.. ah well, too late now, I'm not going to go through the whole process yet another time! So finally I can check out and my credit card is charged. However, since my credit card is hit by a multitude of different vendors that use Amazon as a front, within seconds of each other, some transactions are rejected as my credit card does not allow too many transactions in too short a time (some sort of security feature?). Finally, after getting a few emails from Amazon saying the card could not be charged, and then telling Amazon to retry, my order is at last paid for and on the way.</p>
<p>Okay, so what could be done to make this better?</p>
<ol>
<li>Allow buyers to filter their results so they only see books that can be delivered to their addresses.</li>
<li>Do not use patronising messages like "there is a slight problem".</li>
<li>Do not suggest that people change their delivery address to another country.. that is clearly not going to happen!</li>
<li>Show the cost of postage all throughout the process. Book buyers know they are going to have to pay postage and want to optimise their orders taking it into account.</li>
<li>Do not show the order total including postage for the first time as a confusing advertisement ("With an Amazon credit card, this order would be $324 rather than $368"). Instead, provide a simple breakdown in a table, including postage on each book.</li>
<li>Hit the credit card once per order, and divvy up the money at Amazon internally, rather than allowing each book vendor to do it and having credit card rejections as a result.</li>
</ol>
<p><span style="font-weight: bold">UPDATE:</span> My books arrived about two weeks after I ordered them. Delivery was smooth and on time. Unfortunately, one of the <span class="blsp-spelling-error" id="SPELLING_ERROR_0">CDs</span> that came with a book was broken. Amazon has kindly agreed to replace it and the book.</p>
<p><a href="http://bp3.blogger.com/_TlhwVaDeyBE/RiiAOfUwAAI/AAAAAAAAAW0/9Jx_WNvCA0Y/s1600-h/IMG_1941.JPG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img src="http://bp3.blogger.com/_TlhwVaDeyBE/RiiAOfUwAAI/AAAAAAAAAW0/9Jx_WNvCA0Y/s400/IMG_1941.JPG" style="margin: 0pt 10px 10px 0pt auto; cursor: pointer" id="BLOGGER_PHOTO_ID_5055431568138436610" border="0" /></a></p>
<div style="clear: both">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/04/18/experience-of-an-international-amazon-virgin/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tips for Developing Mephisto Plugins with Liquid and Rails</title>
		<link>http://jamescrisp.org/2007/04/11/tips-for-developing-mephisto-plugins-with-liquid-and-rails/</link>
		<comments>http://jamescrisp.org/2007/04/11/tips-for-developing-mephisto-plugins-with-liquid-and-rails/#comments</comments>
		<pubDate>Thu, 12 Apr 2007 04:32:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Mephisto]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=56</guid>
		<description><![CDATA[When I was writing a contact form plugin for Mephisto, I had a lot of trouble finding documentation and ended up reading lots of code and experimenting. That was fun, but fairly slow, so I hope this post can save future plugin developers time, and help them avoid some of the gotchas I stumbled over.
Repository [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-weight: bold;"></span>When I was writing a <a href="http://jamescrisp.org/2007/03/19/contact-feedback-form-plugin-for-mephisto/">contact form plugin</a> for <a href="http://mephistoblog.com/">Mephisto</a>, I had a lot of trouble finding documentation and ended up reading lots of code and experimenting. That was fun, but fairly slow, so I hope this post can save future plugin developers time, and help them avoid some of the gotchas I stumbled over.</p>
<p><span style="font-weight: bold;">Repository Directory Structure</span><br />At the most macro level, your repository needs to have a 'plugins' directory, and then a directory named after your plugin. Eg,<br />.../plugins/my_new_plugin/...<br />If this is not set up correctly, your plugin will not be able to be installed via 'ruby script/install plugin <repository>' method.</p>
<p></repository><span style="font-weight: bold;">Liquid Plugins Directory and Init.rb</span><br />As you probably know, Mephisto uses <a href="http://home.leetsoft.com/liquid">Liquid</a> for page templates. Liquid can be extended with new tags/blocks. The way to do this in a plugin is to set up a 'mephisto/liquid' directory with your extensions in it. See <a href="http://mephisto-contact-form-plugin.googlecode.com/svn/plugins/mephisto_contact_form/lib/mephisto/liquid/">example here</a>. So that's great, but you also need to register it in init.rb. Here's the contact form's <a href="http://mephisto-contact-form-plugin.googlecode.com/svn/plugins/mephisto_contact_form/init.rb">init.rb</a> - check out the line about 'register_tag'.</p>
<p><span style="font-weight: bold;">Mephisto Plugin Class</span><br />Mephisto trunk now has a base class for plugins - Mephisto::Plugin. Inheriting from this allows you to set up routes to brand new controllers you create. See <a href="http://mephisto-contact-form-plugin.googlecode.com/svn/plugins/mephisto_contact_form/lib/plugin.rb">contact form example here</a>.  This opens the door to writing Mephisto plugins which do postback and processing. It is also possible to add in tabs and forms in the administration interface. <a href="http://techno-weenie.net/">Rick</a>'s <a href="http://svn.techno-weenie.net/projects/mephisto/plugins/mephisto_feedback/lib/plugin.rb">feedback plugin</a> shows how to do this.</p>
<p><span style="font-weight: bold;">Using Liquid Templates from Your Plugin</span><br />One of the trickiest bits was getting the plug-in controller to render a liquid template. This is important if you want your additions to Mephisto to have the same layout and colours as the rest of the site. The way I'll outline below works fine, but it is not ideal. Hopefully there is a better way to do this (eg, some sort of Liquid API for Mephisto plugins).. if you know how a better way, please let me know!</p>
<p>I had my plugin controller inherit from the Mephisto ApplicationController to gain access to the method 'render_liquid_template_for'. You can see the <a href="http://mephisto-contact-form-plugin.googlecode.com/svn/plugins/mephisto_contact_form/lib/controllers/contact_form_controller.rb">code here</a>. However, this led to thorny problems where the plug-in classes were getting loaded only once when the server started, but Mephisto (and the ApplicationController) were getting reloaded for every request. First request worked fine, but nasty errors were spat out on the second and subsequent requests. To resolve this, I removed the plug-in from the 'load_once_paths'. You can see how to do this in the <a href="http://mephisto-contact-form-plugin.googlecode.com/svn/plugins/mephisto_contact_form/init.rb">init.rb</a>.</p>
<p><span style="font-weight: bold;">Models, Views &#038; Controllers Directories and Init.rb</span><br />Okay, this is open to personal taste. I like to have similar directories in my plugin to a normal app. Eg, separate directories for controllers, model, etc. This causes a bit more work, as you need to add the extra directories to various global path variables. For an example of how to do this, take a look at 'models_path' and 'controllers_path' in this <a href="http://mephisto-contact-form-plugin.googlecode.com/svn/plugins/mephisto_contact_form/init.rb">init.rb</a> and the physical directory structure of the <a href="http://mephisto-contact-form-plugin.googlecode.com/svn/plugins/mephisto_contact_form/lib/">contact form's lib directory</a>.<br /><span style="font-weight: bold;"><br /></span></p>
<p><b>UPDATE</b><br />
More info about <a href="http://jamescrisp.org/2008/08/25/migrating-mephisto-plugins-to-drax-08/">Mephisto plugins with Drax 0.8</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/04/11/tips-for-developing-mephisto-plugins-with-liquid-and-rails/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Improve Rails Performance Through Eternal Browser Caching of Assets</title>
		<link>http://jamescrisp.org/2007/04/03/improve-rails-performance-through-eternal-browser-caching-of-assets/</link>
		<comments>http://jamescrisp.org/2007/04/03/improve-rails-performance-through-eternal-browser-caching-of-assets/#comments</comments>
		<pubDate>Tue, 03 Apr 2007 13:11:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=55</guid>
		<description><![CDATA[I've been working on a rails app which has got quite a number of pages that share the same two css files and 3 javascript files. However, every time I visited any page of the app, all of javascripts and css files were being loaded from the server. Not good - site was very slow. [...]]]></description>
			<content:encoded><![CDATA[<p>I've been working on a rails app which has got quite a number of pages that share the same two css files and 3 javascript files. However, every time I visited any page of the app, all of javascripts and css files were being loaded from the server. Not good - site was very slow. Mucking around with 'about:cache' command in Firefox revealed that the css and javascript files had expiry dates set in the past - ie, no caching of them at all. Also, all the links to sylesheets and javascript files generated by rails had ?<long>[some long number] after them. Some <a href="http://www.endikos.com/2007/2/23/rails-asset-id-and-seo">research on the web</a> revealed that this is a new rails feature for caching - the long number is a timestamp for when the asset was last modified.</p>
<p>Okay, so why were these assets not being cached? A quick check with wget --save-headers revealed that the web server was sending a nocache directive to the browser. This seems to be the default setup for webrick and also for my shared apache hosting on <a href="http://railsplayground.com/">railsplayground</a>. Considering the new rails asset management system with the ?<last>[last modified timestamp] in the URLs, nocache seems wrong. The browser should never expire the cache since rails will handle cache invalidation by updating the asset url with a new timestamp.</p>
<p>So, how can we implement no/very long cache expiry? In apache, you can use mod_expires or mod_headers to do this. My shared hosting does not support mod_expires, so I went for mod_headers in my .htaccess file.</p>
<p>Using mod_headers:</p>
<pre><filesmatch>&lt;FilesMatch ".*$"&gt;
Header set Cache-Control "max-age=29030400"
&lt;/FilesMatch&gt;</filesmatch></pre>
<p>OR using mod_expires:</p>
<pre>ExpiresActive On
ExpiresDefault "access plus 1 year"</pre>
<p>Either of the the above will set up a cache expiry time of one year for all content (best you only do this for your rails app directories).</p>
<p>With a cache expiry time of one year in place, my rails apps run much much faster.</last></long></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/04/03/improve-rails-performance-through-eternal-browser-caching-of-assets/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Naked Economics by Charles Wheelan</title>
		<link>http://jamescrisp.org/2007/04/03/naked-economics-by-charles-wheelan/</link>
		<comments>http://jamescrisp.org/2007/04/03/naked-economics-by-charles-wheelan/#comments</comments>
		<pubDate>Tue, 03 Apr 2007 11:19:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Finance]]></category>

		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=54</guid>
		<description><![CDATA[Just finished reading 'Naked Economics: Undressing the dismal science'. It was a present from a friend, and I've been meaning to read it for a while. Glad I finally got around to it.
From the title, I assumed the book aimed to point out the failures of economics as a science. Not so at all - [...]]]></description>
			<content:encoded><![CDATA[<p>Just finished reading 'Naked Economics: Undressing the dismal science'. It was a present from a friend, and I've been meaning to read it for a while. Glad I finally got around to it.</p>
<p>From the title, I assumed the book aimed to point out the failures of economics as a science. Not so at all - it was written by an economist and provides a high level overview of capitalism in layman's terms.</p>
<p>Here's some interesting questions and explanations from the book:
<ul>
<li>Why do we have money? So that we can indirectly swap our labour or goods for the things we want, even if the person with the things we want is not interested in our labour or goods. Without money, we would need to barter. That's fine if you're swapping chickens for rice. But what happens if you do web design, and you want meat for dinner, and the butcher does not want a website?</li>
<li>Money has value only because we all believe it does. We have faith that if we sell something (<span class="blsp-spelling-error" id="SPELLING_ERROR_0">ie</span>, convert it to the common value unit), we will then be able to swap that money for something we want.</li>
<li>Why have markets anyway? Markets produce what people want - <span class="blsp-spelling-error" id="SPELLING_ERROR_1">ie</span>, what people are willing to pay for (or at least what we are convinced into wanting through advertising etc).</li>
<li>Why not set the price of everything rather than letting it get worked out in a market? Well, it would be an enormous job, and things would not reflect the cost of production. <span class="blsp-spelling-error" id="SPELLING_ERROR_2">Eg</span>, bird flu wipes out half of the chickens in the world. There are now less chickens to go around so chicken becomes more expensive. People who really want chicken can still get it, but it costs them more. People who don't care as much or can't afford it eat fish or beef instead. If the cost of chicken was a constant mandated by the state, chicken distribution would need to be mandated in some other way. If there's not enough chicken for everyone who wants it, who should get it? First come first served? Political clout? Personal connections?</li>
<li>Markets destroy. A new way to mechanize weaving may make thousands unemployed and destroy towns and communities. But according to <span class="blsp-spelling-error" id="SPELLING_ERROR_3">Wheelan</span>, the country as a whole is better off as we are able to produce more for less cost, hence increasing our standard of living. <span class="blsp-spelling-error" id="SPELLING_ERROR_4">Ie</span>, as a consumer, you may now be able to buy a shirt for half the price.</li>
<li>In politics, small motivated groups often drive policy. <span class="blsp-spelling-error" id="SPELLING_ERROR_5">Eg</span>, the general population does not care much one way or other on a subsidy on growing alfalfa. It might cost each person in Australia 0.01c per year. However, if the subsidy was to be removed,  and the alfalfa farmers would care a lot. It may well mean their livelihoods so they would demonstrate, make campaign donations, vote as a block and generally make as much fuss as possible to make sure the subsidy was not removed.</li>
<li>Why do people work in sweatshops? According to <span class="blsp-spelling-error" id="SPELLING_ERROR_6">Wheelan</span>, the pay is generally better than for other jobs available - <span class="blsp-spelling-error" id="SPELLING_ERROR_7">ie</span>, sweatshops are not the cause of the problem, rather a symptom of the general poverty and lack of opportunity in the area.</li>
<li>Why is free trade good? So that everyone can do what they do best - <span class="blsp-spelling-error" id="SPELLING_ERROR_8">ie</span>, specialise to the max. The idea being that if everyone works on what they are most good at, then productivity overall is higher.</li>
<li>Why are tariffs bad? Because they support local industries that are not viable - <span class="blsp-spelling-error" id="SPELLING_ERROR_9">ie</span>, a poor uses of resources.</li>
<li>Why do we need governments? To provide the rails for capitalism. <span class="blsp-spelling-error" id="SPELLING_ERROR_10">Eg</span>, to enforce laws (so you can't just kill me and take my stuff), to regulate the excesses of the free market and to provide goods and services that people need but that free markets will never provide. Also, to do things that individuals cannot do alone, but are in the interest of the population as a whole - <span class="blsp-spelling-error" id="SPELLING_ERROR_11">eg</span>, build infrastructure.</li>
<li>Care for the environment is a luxury good - <span class="blsp-spelling-error" id="SPELLING_ERROR_12">ie</span>, if you and your family are starving, cutting down trees to sell for food seems like a pretty good idea.</li>
<li>Companies destroy the environment because the current monetary cost of environmental destruction is usually minimal. If the full cost of environmental destruction was factored into the market (<span class="blsp-spelling-error" id="SPELLING_ERROR_13">eg</span>, companies have to pay for pollution and destruction), then environmental destruction would slow dramatically.</li>
<li>Who can create new money? The reserve bank, and it does it by buying bonds from banks with money that did not previously exist.</li>
<li>How can the reserve bank change interest rates? It can sell government bonds at its target rate and it can buy bonds (with brand new money) or sell bonds from/to trading banks to influence the amount of cash the banks have to lend. <span class="blsp-spelling-error" id="SPELLING_ERROR_14">Eg</span>, lots of cash at a trading bank means they'll lower the interest rates so as to rent out the money.</li>
<li>How come the economy can go into recession for no real reason? If people are worried, they don't spend. If people don't spend, then companies can't afford new/current investment. People get sacked and then can spend even less. People get more worried and the cycle continues.</li>
<li>Why is the level of savings in a country important? Money in the bank means it can be <span class="blsp-spelling-corrected" id="SPELLING_ERROR_15">lent</span> out to people who want to use it to create new businesses or expand current businesses. Access to capital allows growth.</li>
</ul>
<p>I wouldn't take these on face value, and I would certainly question some of the assumptions on which they are based. However, they provide some interesting areas for further thought.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/04/03/naked-economics-by-charles-wheelan/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Starting at ThoughtWorks: First Five Weeks</title>
		<link>http://jamescrisp.org/2007/03/26/starting-at-thoughtworks-first-five-weeks/</link>
		<comments>http://jamescrisp.org/2007/03/26/starting-at-thoughtworks-first-five-weeks/#comments</comments>
		<pubDate>Tue, 27 Mar 2007 04:11:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=52</guid>
		<description><![CDATA[Well, I've been with ThoughtWorks for just over 5 weeks now, and I thought I'd write down some thoughts before the hiring and joining process got lost in the misty swamp of my memory.
Hiring processTo cut a long story short, I did a phone screen with HR, a coding test and then some fairly quick [...]]]></description>
			<content:encoded><![CDATA[<p>Well, I've been with <a href="http://www.thoughtworks.com/">ThoughtWorks</a> for just over 5 weeks now, and I thought I'd write down some thoughts before the hiring and joining process got lost in the misty swamp of my memory.</p>
<p><span style="font-weight: bold;">Hiring process</span><br />To cut a long story short, I did a phone screen with HR, a coding test and then some fairly quick aptitude and personality tests and finally 3 interviews. You have something like a week to do the coding test and then submit your code for review. I had the other tests and interviews on a single day. Although this sounds pretty horrendous, it actually wasn't too bad. Tests were pretty quick and the interviewers were astoundingly friendly. I finished by something like 3pm in the afternoon, including a lunch break, and surprisingly didn't feel too bad or stressed afterwards.</p>
<p><span style="font-weight: bold;">Induction</span><br />As a fairly impressive start, I had 2 days of induction in Melbourne (I live in Sydney). ThoughtWorks arranged drivers, hotel and flight so it was all very smooth. This was lucky as I was pretty jet lagged and confused - I'd just flown back from an <a href="http://jamescrisp.blogspot.com/search/label/Travel">overseas holiday</a> not long before. Induction was largely getting a company provided laptop, meeting people and getting an introduction to various internal systems and procedures. As an aside, I've heard that there is now an "immersion" process where you get sent to India for a week or two for induction but can't comment on that.</p>
<p><span style="font-weight: bold;">A few weeks on the beach</span><br />When you're not assigned to a client project, you are "on the beach". This means you go into your local office with your laptop. It's really great - there's no particular tasks assigned to you, but the opportunity is there to get involved in a lot of interesting stuff. To give you some examples, here's some of the stuff I've had the chance to do:
<ul>
<li>Write an <a href="http://jamescrisp.blogspot.com/2007/03/contact-feedback-form-plugin-for.html">open source plug-in for Mephisto</a> for <a href="http://studios.thoughtworks.com/">ThoughtWorks Studios</a></li>
<li>Be involved in scoping out and estimating for a RFI from a new client</li>
<li>Pair with another developer to do code reviews of potential new recruits</li>
<li>Help out briefly with a fun project to develop a <a href="http://sourceforge.net/projects/jcruisemonitor/">driver for a USB build light</a> for continuous integration servers (red for broken build, green for good build, etc)</li>
<li>Help out on client projects - I was asked to whip up a little proof of concept for JRuby and Java integration and <a href="http://jamescrisp.blogspot.com/2007/02/jruby-setup.html">learnt a bit</a> getting this set up</li>
<li>Do a little bit of Google Maps integration</li>
<li>Meet colleagues and learn more about procedures etc</li>
<li>Get invited to lunch with the managing director - this is something that happens for all new hires and I think it's really great</li>
<li>Almost go out on a pre-sales call (I've got to go back to Melbourne and will miss this unfortunately)</li>
<li>Catch up on tech reading such as blogs, books etc</li>
<li>Go to a swanky <a href="http://www.thoughtworks.com.au/tech-briefing.html">talk</a> given by Martin Fowler and  Kristan Vingrys</li>
<li>Eat lots of free lunches (usually twice a week) and attend various talks at the office given by other consultants</li>
<li>Drink lots of free coffee (ThoughtWorks has a coffee tab with a local cafe)</li>
</ul>
<p><span style="font-weight: bold;">First project<span style="font-weight: bold;"></span><br /></span>Much fun as it is on the beach, after a few weeks, I was itching to join the big boys and go on a project. Getting assigned to a project is the purview of your professional services manager, and can be pretty changeable. The saying is that "you don't really know what project you're on till you walk in the door of the client site" and I've even heard "you don't really know what project you're on till you're on the plane home". There's a grain of truth in these - it can look like you are going to go on a project and then it doesn't come through, or some other project becomes more important or whatever. I almost went on several different projects before finally ending up on quite a cool Ruby / Rails project with a startup in Melbourne. So, I got to join the jet set and have been flying down to Melbourne during the week, and back for the weekends. This is a bit tiring, but ThoughtWorks does its best to make things comfortable. I'm staying in a really nice corporate apartment in Melbourne, flights are arranged and paid for and drivers are scheduled for pickup and drop off to the airport. There's also a generous per diem allowance for food. The project is really cool, and I'm enjoying it, but can't say more as it is under a NDA.</p>
<p><span style="font-weight: bold;">Back on the beach.. but only for two days!<br /></span>My first project was two weeks, so after that I returned to the beach. Today is my second day on the beach. However, it turns out that the client was very happy with our first two weeks work and they've invited us back again until Easter. This means I need to fly back to Melbourne tomorrow.  This won't continue indefinitely though - when I was discussing the project with my professional services manager, we agreed that I would not need to stay on a Melbourne project for more than 6 weeks. And clearly this is in ThoughtWorks interest as well - it costs a lot more to fly somebody in from Sydney every week and provide accommodation etc. I'm going to be transitioning off the project by Easter and a Melbourne based consultant is going to take over from me if the project continues further. It'll be good to be on a Sydney based project again but I feel it would be unfair not to say that ThoughtWorks has done a really good job in making working in another city as convenient and pleasant as possible.</p>
<p><span style="font-weight: bold;">Various benefits<br /></span>ThoughtWorks is pretty generous in the expenses department. They cover your mobile phone, home internet, per diem when away, give an allowance for training courses and books, etc. There's also lots of free lunches, food, coffee and catered events.</p>
<p><span style="font-weight: bold;">Transparency and knowing what's going on<br /></span>I've been quite impressed to get a monthly update email that talks about ThoughtWorks plans, goals and financials, headcount etc in significant detail. There's also various update meeting where you get to hear how projects are going and what's happening with various clients. Personally I'm really glad to see this type of thing, as at previous jobs, this has been privileged information, and most of the time, I have not really had any idea how well the company is doing financially as a whole, or what the future plans and directions are.</p>
<p><span style="font-weight: bold;">Variety and Unpredictability<br /></span>These are really two faces of the same coin, and depending on your character and experience, I think you might either love or hate this. You really don't know what project you're going to be working on, what your role will be, what industry the client is in, what type of development they need or for what platform or in what language. In fact, you don't even know what city you're going to be in during a given week. I'm enjoying this at this point as my last job was always in the same office, with the same technologies etc. However, I can see it may be trying in the long term, and it does make it difficult to do the shopping or organise things with friends during the week. On the other hand, I have heard that most of the work in Sydney is for big companies like banks and telcos in the city CBD within walking distance to the office, and the majority in Java. So perhaps my short experience so far is not the norm.</p>
<p><span style="font-weight: bold;">In conclusion...<br /></span>So far, I can honestly say that it's been really great working at ThoughtWorks. I've had a chance to do some of the stuff I've wanted to do for ages like work on a bit of open source and do some commercial Ruby on Rails work. My colleagues have been friendly and welcoming, and I've been wowed by the level of care that ThoughtWorks takes of its employees.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/03/26/starting-at-thoughtworks-first-five-weeks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Contact / Feedback Form Plugin for Mephisto</title>
		<link>http://jamescrisp.org/2007/03/19/contact-feedback-form-plugin-for-mephisto/</link>
		<comments>http://jamescrisp.org/2007/03/19/contact-feedback-form-plugin-for-mephisto/#comments</comments>
		<pubDate>Mon, 19 Mar 2007 11:26:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Mephisto]]></category>

		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=50</guid>
		<description><![CDATA[Introduction
If you use Mephisto, a content management / blogging system written in Rails, you may well be interested in using this new plug-in. It provides a form that lets visitors to your site leave their contact details and send you messages or feedback via email.
UPDATE
Please check out information about using the contact form plugin with [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://bp1.blogger.com/_TlhwVaDeyBE/Re9LzKIAXII/AAAAAAAAAWg/Ymx_wzpmPdM/s1600-h/plugin.JPG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img src="http://bp1.blogger.com/_TlhwVaDeyBE/Re9LzKIAXII/AAAAAAAAAWg/Ymx_wzpmPdM/s200/plugin.JPG" style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer" id="BLOGGER_PHOTO_ID_5039329850314218626" border="0" /></a><span style="font-weight: bold">Introduction</span><br />
If you use <a href="http://mephistoblog.com/">Mephisto</a>, a content management / blogging system written in <a href="http://www.rubyonrails.org/">Rails</a>, you may well be interested in using this new plug-in. It provides a form that lets visitors to your site leave their contact details and send you messages or feedback via email.</p>
<p><strong>UPDATE</strong><br />
Please check out information about <a href="http://jamescrisp.org/2008/08/25/contact-form-for-mephisto-updated-for-drax-08/">using the contact form plugin with Mephisto Drax 0.8</a>.</p>
<p><span style="font-weight: bold">License</span><br />
This plug-in was developed for the new <a href="http://studios.thoughtworks.com/">ThoughtWorks Studios site</a>. As I wrote it at and for work, it is copyright ThoughtWorks, 2007. However, ThoughtWorks, being generous souls, is happy for me to open source it under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache 2.0 licence</a>, which pretty much means you have free reign to use it as you want.</p>
<p><span style="font-weight: bold">Requirements</span></p>
<ul>
<li>Mephisto Edge (the latest stable 0.7.3 release does not have support for Mephisto plugins)</li>
<li>Rails Edge (required by Mephisto edge)</li>
<li>ActionMailer (comes with Rails) correctly configured with SMTP server etc, so that emails can be delivered. See "Configuration" section <a href="http://wiki.rubyonrails.org/rails/pages/HowToSendEmailsWithActionMailer">here</a> for more details.</li>
</ul>
<p><span style="font-weight: bold">Installation</span></p>
<pre>ruby script/plugin install http://github.com/jcrisp/mephisto_contact_form/tree/master</pre>
<p>or in your vendor/plugins directory for Mephisto:</p>
<pre>git clone http://github.com/jcrisp/mephisto_contact_form/tree/master mephisto_contact_form</pre>
<p>Make sure you restart your web server at this point so that the plugin is loaded.</p>
<p><span style="font-weight: bold">Setup</span><br />
1. Create a new template called 'contact_us.liquid' though the admin web interface (under the 'Design' tab).<br />
Paste in the following code:</p>
<pre>
&lt;H1&gt;Contact Us&lt;/H1&gt;
{% contactform %}
&lt;p&gt;{{ form.name }}&lt;label for="author"&gt;&lt;small&gt;Your name&lt;/small&gt;&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;{{ form.email }}&lt;label for="email"&gt;&lt;small&gt;Email address&lt;/small&gt;&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;{{ form.phone}}&lt;label for="phone"&gt;&lt;small&gt;Phone number (optional)&lt;/small&gt;&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;{{ form.subject}}&lt;label for="subject"&gt;&lt;small&gt;Subject&lt;/small&gt;&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;{{ form.body }}&lt;/p&gt;
&lt;p&gt;{{ form.submit }}&lt;/p&gt;
{% endcontactform %}</pre>
<p>Feel free to modify labels, layout etc.</p>
<p>2. Edit</p>
<pre>{MEPHISTO_ROOT}/vendor/plugins/mephisto_contact_form/lib/contact_notifier.rb</pre>
<p>and put in the email address you want contact form submissions to go to.</p>
<p>3. Link to "/contact_form" from your site.</p>
<p><span style="font-weight: bold">Any issues / questions / suggestions?</span><br />
Best to post comments on this blog.</p>
<p><span style="font-weight: bold">Technical Info<br />
</span>The contact form plugin is actually a combination of a rails plugin, a liquid block plugin and a Mephisto plugin. See this post about <a href="http://jamescrisp.org/2007/04/11/tips-for-developing-mephisto-plugins-with-liquid-and-rails/">developing Mephisto plugins</a> for more information.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/03/19/contact-feedback-form-plugin-for-mephisto/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Secrets of Consulting by Gerald Weinberg</title>
		<link>http://jamescrisp.org/2007/03/05/the-secrets-of-consulting-by-gerald-weinberg/</link>
		<comments>http://jamescrisp.org/2007/03/05/the-secrets-of-consulting-by-gerald-weinberg/#comments</comments>
		<pubDate>Mon, 05 Mar 2007 11:04:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Soft Skills and Mind Hacks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=48</guid>
		<description><![CDATA[The Secrets of Consulting by Gerald Weinberg is one of the most entertaining (largely?) non-fiction books that I have read - a heady mix of How to Win Friends and Influence People, Fear and Loathing in Las Vegas (just look at the illustrations!) , and the 10 Commandments. The book provides general advice, case studies/stories [...]]]></description>
			<content:encoded><![CDATA[<p>The Secrets of Consulting by Gerald Weinberg is one of the most entertaining (largely?) non-fiction books that I have read - a heady mix of <a href="http://jamescrisp.blogspot.com/2007/01/how-to-win-friends-and-influence-people.html">How to Win Friends and Influence People</a>, <a href="http://en.wikipedia.org/wiki/Fear_and_Loathing_in_Las_Vegas">Fear and Loathing in <span class="blsp-spelling-error" id="SPELLING_ERROR_0">Las</span> Vegas</a> (just look at the illustrations!) , and the <a href="http://en.wikipedia.org/wiki/Ten_Commandments">10 Commandments</a>. The book provides general advice, case studies/stories and then derives general "rules" and recommendations from these.</p>
<p>Personally, I found the chapter on the pricing of consulting to be particularly interesting. Thinking about setting a price previously, I would have suggested it should be enough to cover costs and make a bit of a profit. Weinberg points out that price is more than this - it is a big factor in the relationship and the level of respect for the consultant.</p>
<p>The Weinberg's consulting "rules" are quite numerous - my personal favourites are:
<ul>
<li>"If you can't fix it, feature it."</li>
<li>"It may look like a crisis, but it's only the end of an illusion." </li>
<li>"You'll never accomplish anything if you care who gets the credit."</li>
<li>"If <span class="blsp-spelling-error" id="SPELLING_ERROR_1">something's</span> faked, it must need fixing."</li>
<li>"The name of the thing [label] is not the thing."</li>
<li>"It tastes better when you add your own egg."</li>
<li>"You don't get <span class="blsp-spelling-error" id="SPELLING_ERROR_2">nothin</span>' for <span class="blsp-spelling-error" id="SPELLING_ERROR_3">nothin</span>'. Moving in one direction incurs a cost in the other."</li>
<li>"Whatever the client is doing, advice something else."</li>
<li>"What you don't know may not hurt you, but what you don't remember always does."</li>
<li>"Clients always know how to solve their problems and always tell the solution in the first five minutes."</li>
<li>"When change is inevitable, we struggle most to keep what we value most."</li>
<li>"The biggest and longest lasting changes usually originate in attempts to preserve the very thing ultimately changes most."</li>
<li>"Effective problem-solvers may have many problems, but rarely have a single, dominant problem."</li>
<li>"Make sure they pay you enough so they'll do what you say. The most important act in consulting is setting the right fee."</li>
<li>"The more they pay you, the more they love you. The less they pay you, the less they respect you."</li>
<li>"Spend at least one day a week getting exposure." and "Spend at least 1/4 of your time doing nothing." and make sure your fee covers this.</li>
<li>"Set a price so you won't regret it either way."</li>
<li>"If they don't like your work, don't take their money."</li>
<li>"Cucumbers get more pickled than brine gets <span class="blsp-spelling-error" id="SPELLING_ERROR_4">cucumbered</span>."</li>
<li>"Give away your best ideas."</li>
<li>"Look for what you like in the present situation and comment on it."</li>
<li>"Study for understanding, not for criticism."</li>
<li>"Never promise more than 10% improvement.. if you happen to achieve more than 10% improvement, make sure it isn't noticed."</li>
<li>"Consultants tend to be the most effective on the third problem you give them."</li>
<li>"The child who receives a hammer for Christmas will discover that everything needs pounding."</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/03/05/the-secrets-of-consulting-by-gerald-weinberg/feed/</wfw:commentRss>
		</item>
		<item>
		<title>_vimrc for Ruby</title>
		<link>http://jamescrisp.org/2007/03/01/_vimrc-for-ruby/</link>
		<comments>http://jamescrisp.org/2007/03/01/_vimrc-for-ruby/#comments</comments>
		<pubDate>Thu, 01 Mar 2007 11:18:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=46</guid>
		<description><![CDATA[In the past I've used gvim for Ruby coding. It's been pretty good, especially with the new tabbed editing and omni complete (bit like intellisense in Visual Studio) introduced in vim 7. However, when I downloaded vim at work, I was missing the secret sauce - a good vimrc. Here's my usual vimrc for ruby:
set [...]]]></description>
			<content:encoded><![CDATA[<p>In the past I've used gvim for Ruby coding. It's been pretty good, especially with the new tabbed editing and omni complete (bit like intellisense in Visual Studio) introduced in vim 7. However, when I downloaded vim at work, I was missing the secret sauce - a good vimrc. Here's my usual vimrc for ruby:</p>
<pre>set nocompatible
behave xtermset
selectmode=mouse
set nu
set tabstop=2
set shiftwidth=2
set softtabstop=2
set ai
set columns=100
set lines=70
set guifont=Courier:h10
set expandtab
set smarttab
let g:rubycomplete_rails = 1</pre>
<p>Among other things, it makes the default window size bigger, uses a prettier font, sets up auto indenting ruby style, and turns on omni-complete.</p>
<p>By the way, on windows, assuming a default install, vimrc is to be found here:</p>
<pre>C:\Program Files\Vim\_vimrc</pre>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/03/01/_vimrc-for-ruby/feed/</wfw:commentRss>
		</item>
		<item>
		<title>JRuby Setup</title>
		<link>http://jamescrisp.org/2007/02/26/jruby-setup/</link>
		<comments>http://jamescrisp.org/2007/02/26/jruby-setup/#comments</comments>
		<pubDate>Tue, 27 Feb 2007 04:59:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=45</guid>
		<description><![CDATA[Recently got a JRuby/Rails system with Java integration up and running. Unfortunately, it took quite a few hours, as most of the docs and code you find through Google are out of date.
If you use JRuby 0.9.2 from Codehaus, you will get an error similar to this when you try to access a rails application:
[2007-02-26 [...]]]></description>
			<content:encoded><![CDATA[<p>Recently got a JRuby/Rails system with Java integration up and running. Unfortunately, it took quite a few hours, as most of the docs and code you find through Google are out of date.</p>
<p>If you use JRuby 0.9.2 from Codehaus, you will get an error similar to this when you try to access a rails application:</p>
<p>[2007-02-26 17:54:59] INFO  WEBrick::HTTPServer start: pid=22540508 port=3000<br />&lt;ArgumentError: Anonymous modules have no name to be referenced by&gt;<br />["c:/jruby-0.9.2/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/<br />active_support/dependencies.rb:402:in `to_constant_name'...</p>
<p>If you're stuck in this rut, fear not!  <a href="http://blog.nicksieger.com/">Nick Sieger</a>  has written <a href="http://trac.caldersphere.net/projects/main/wiki/JRubyQuickStart">very helpful instructions</a> which outline how to get and set up the latest development snapshot. Please note that in addition to the instructions, you need to set your JRUBY_HOME environment variable. Under Windows, do something like this:</p>
<p>set JRUBY_HOME=c:\jruby</p>
<p>If you'd prefer not to use the snapshot, you can get the source code through subversion from: </p>
<p><a href="http://svn.codehaus.org/jruby/trunk/jruby">http://svn.codehaus.org/jruby/trunk/jruby</a></p>
<p>but at the time of this post, you need to run svn checkout or update with "--ignore-externals" to avoid the following error:</p>
<p>Error: URL 'svn://rubyforge.org/var/svn/bfts/bfts/trunk' doesn't exist</p>
<p>Many thanks to <a href="http://blog.nicksieger.com/">Nick Sieger</a> and the <a href="http://archive.jruby.codehaus.org/user">JRuby user mailing list</a> for their help.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/02/26/jruby-setup/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Using floating point variables to represent money =&gt; not a good idea!</title>
		<link>http://jamescrisp.org/2007/02/25/using-floating-point-variables-to-represent-money-not-a-good-idea/</link>
		<comments>http://jamescrisp.org/2007/02/25/using-floating-point-variables-to-represent-money-not-a-good-idea/#comments</comments>
		<pubDate>Sun, 25 Feb 2007 10:59:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=42</guid>
		<description><![CDATA[I was reading through some code the other day and was surprised to find that it was using doubles to represent  dollar amounts. Reason for the alarm bells is that doubles and floats cannot accurately represent many decimal fractions (eg, 0.1), since doubles and floats internally work with powers of 2 rather than powers [...]]]></description>
			<content:encoded><![CDATA[<p>I was reading through some code the other day and was surprised to find that it was using doubles to represent  dollar amounts. Reason for the alarm bells is that doubles and floats cannot accurately represent many decimal fractions (<span class="blsp-spelling-error" id="SPELLING_ERROR_0">eg</span>, 0.1), since doubles and floats internally work with powers of 2 rather than powers of 10. These inaccuracies are likely to lead to significant errors, especially when performing arithmetic (<span class="blsp-spelling-error" id="SPELLING_ERROR_1">eg</span>, adding up a table of dollar amounts). See this <a href="http://www2.hursley.ibm.com/decimal/decifaq1.html#inexact">IBM article</a> for a more <span class="blsp-spelling-corrected" id="SPELLING_ERROR_2">in depth</span> explanation and examples. The solution is to use types that work with powers of ten internally. In C#, you can use 'decimal' and in Java or Ruby, '<span class="blsp-spelling-error" id="SPELLING_ERROR_3">BigDecimal</span>', to avoid these problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/02/25/using-floating-point-variables-to-represent-money-not-a-good-idea/feed/</wfw:commentRss>
		</item>
		<item>
		<title>AntiPattern: BusinessObjects in the driving seat</title>
		<link>http://jamescrisp.org/2007/01/11/antipattern-businessobjects-in-the-driving-seat/</link>
		<comments>http://jamescrisp.org/2007/01/11/antipattern-businessobjects-in-the-driving-seat/#comments</comments>
		<pubDate>Fri, 12 Jan 2007 00:51:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Design / Architecture]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=37</guid>
		<description><![CDATA[When you have a rich domain model with a business object centric design, and a Windows forms GUI, it can be very tempting to start putting significant process logic in the business objects. After continuing along this path a little further, you may realise that the process needs some sort of user input, and you [...]]]></description>
			<content:encoded><![CDATA[<p>When you have a rich domain model with a business object centric design, and a Windows forms GUI, it can be very tempting to start putting significant process logic in the business objects. After continuing along this path a little further, you may realise that the process needs some sort of user input, and you use events or some sort of notifier pattern to gain user input required by the process, while still maintaining layering in terms of referencing. Then additionally you may need to access some sort of external service.</p>
<p>Here is an example:</p>
<pre>class Order : BusinessObject
{
  public void SendOrder(INotifier notifier)
  {
    if (ReadyForDelivery ||
        notifier.Confirm("Are you sure you want to send order lines? They are not ready for delivery."))
    {
      OrderLine[] orders = GetLinesToSend();
      foreach(OrderLine line in Lines)
      {
        SendLine(line); // send line using a web service?
      }

      Notify("Lines sent successfully.");
    }
  }
}

interface INotifier
{
  void Notify(string msg);
  bool Confirm(string msg);
  OrderLine[] GetLinesToSend();
}</pre>
<p>I would like to suggest that this is an anti-pattern and a trap. Although there is no direct reference from the Business Layer to the GUI layer (INotifier is implemented in GUI and passed down), the Business Layer now requires the ability to stay instantiated, pause while waiting for responses from the notifier, and then continue execution. This will work for rich client applications, but not in a stateless web environment. The ideal of being able to swap in/out the GUI layers on top of the Business layer is now compromised.</p>
<p>Instead, it would be possible to drive form the GUI layer, and call a service to send the Order Lines. In pseudo code below:</p>
<pre>void SendMenu_Click(...)
{
  if (Order.ReadyForDelivery ||
      MessageBox.Show(...) == DialogResult.Yes)
  {
    using (ChooseLineForm chooseLineForm = new ChooseLineForm(Order))
    {
      chooseLineForm.ShowDialog()
    }
    SendingSevice.SendLines(chooseLineForm.selectedLines);
    ...
  }
}</pre>
<p>If the logic in the GUI layer became much more complex, it may be a good idea to pull it out into its own class (eg, LineSender). This class would be a type of GUI level controller, responsible for orchestrating the send process.</p>
<p>Using this approach, there are a number of benefits:</p>
<ul>
<li>BusinessObjects have no reliance on GUI implementation, so can be used for Rich Client and Web Client indiscriminately.</li>
<li>Web developers are free to implement the user input process in stateless way more appropriate to their platform.</li>
<li>Functionality for sending Order lines (some sort of integration with a web service?) is pulled out into a service class which can be reused elsewhere (potentially sending other types of objects?) and unclutters the Order business object and removes its dependency  on  an external service.</li>
<li>Code is simpler and easier to follow.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/01/11/antipattern-businessobjects-in-the-driving-seat/feed/</wfw:commentRss>
		</item>
		<item>
		<title>In Defense of Simplicity AND Complexity</title>
		<link>http://jamescrisp.org/2007/01/10/in-defense-of-simplicity-and-complexity/</link>
		<comments>http://jamescrisp.org/2007/01/10/in-defense-of-simplicity-and-complexity/#comments</comments>
		<pubDate>Wed, 10 Jan 2007 22:56:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Design / Architecture]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=36</guid>
		<description><![CDATA[Simplicity and complexity seem to have become hot topics for some of my favourite technical bloggers of late. These fine people have taken the view that things should be either simple or complex. Right, seems logical, these are opposites. However, I would like to suggest that in a well designed appliance which addresses a complex [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.scottberkun.com/blog/?p=502">Simplicity</a> and <a href="http://www.joelonsoftware.com/items/2006/12/09.html">complexity</a> seem to have become hot topics for some of my favourite technical bloggers of late. These fine people have taken the view that things should be either simple or complex. Right, seems logical, these are opposites. However, I would like to suggest that in a well designed appliance which addresses a complex process, it should have both a simple AND a complex interface.</p>
<p>A couple of years ago, I bought a LG "Fuzzy Logic" washing machine. It has lots of buttons and settings on the front and one big button that says something like "Start". 97% of the time, I throw in my washing, some detergent and press the big start button, and the washing machine works out all the settings, displays them and then starts. In the 3% of the time when I want to do something different (eg, just a rinse), I use the more complex part of the interface to change the 'cycle' settings.</p>
<p>Recently, I bought an IXUS 65. It's a lovely digital camera, and it provides both a complex and a simple interface. As soon as I put in the battery, I was able to take pretty nice pictures by just clicking the big button on the top. No problem, I was very happy. Over the next few days, I glanced through the manual and fiddled with more complex settings for ISO, colour etc. However, in 95% of shots, I simply want to click the one big button that takes a nice auto-everything picture. It's only occasionally that I want to change the settings to achieve a particular effect or to override a mistake in the auto settings.</p>
<p>To conclude, I think that my talented fellow bloggers are all right. People like complex interfaces and simple interfaces, just at different times, for different tasks. The best gadgets and appliances offer both.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/01/10/in-defense-of-simplicity-and-complexity/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Pandora - Streaming music</title>
		<link>http://jamescrisp.org/2007/01/05/pandora-streaming-music/</link>
		<comments>http://jamescrisp.org/2007/01/05/pandora-streaming-music/#comments</comments>
		<pubDate>Sat, 06 Jan 2007 02:27:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Music]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=35</guid>
		<description><![CDATA[I'd like to point my readers to Pandora, a streaming music service which lets you define multiple channels for the different types of music that you like. You start each channel with a seed, which is a song or artist that you like. The service chooses songs similar to this and you then mark them [...]]]></description>
			<content:encoded><![CDATA[<p>I'd like to point my readers to <a href="http://www.pandora.com">Pandora</a>, a streaming music service which lets you define multiple channels for the different types of music that you like. You start each channel with a seed, which is a song or <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-corrected" id="SPELLING_ERROR_0">artist</span> that you like. The service <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-corrected" id="SPELLING_ERROR_1">chooses</span> songs similar to this and you then mark them as thumbs up or thumbs down, thus refining the channel more towards your musical taste. It is Flash and browser based, no downloads necessary. Sign up is easy, and the service is free, though add supported. Highly recommended!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2007/01/05/pandora-streaming-music/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Windows Crash: multiple_irp_complete_requests Stop: 0×00000044</title>
		<link>http://jamescrisp.org/2006/12/27/windows-crash-multiple_irp_complete_requests-stop-0x00000044/</link>
		<comments>http://jamescrisp.org/2006/12/27/windows-crash-multiple_irp_complete_requests-stop-0x00000044/#comments</comments>
		<pubDate>Thu, 28 Dec 2006 01:45:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Windows]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=33</guid>
		<description><![CDATA[Thought I'd do a bit of a defrag on my old Windows 2000 box. A few minutes in, I got a blue screen:

multiple_irp_complete_requests
stop: 0x00000044 (0x852CCE68, 0x00000D39, 0x00000000, 0x00000000)

Tried a chkdsk but got the same error, even when running it on boot in console mode.
After some web trawling, found this google answer, which suggested that the [...]]]></description>
			<content:encoded><![CDATA[<p>Thought I'd do a bit of a defrag on my old Windows 2000 box. A few minutes in, I got a blue screen:</p>
<pre>
multiple_irp_complete_requests
stop: 0x00000044 (0x852CCE68, 0x00000D39, 0x00000000, 0x00000000)
</pre>
<p>Tried a chkdsk but got the same error, even when running it on boot in console mode.</p>
<p>After some web trawling, found this <a href="http://answers.google.com/answers/threadview?id=552945">google answer</a>, which suggested that the problem was caused by 'Intel Application Accelerator' conflicting with recent service packs.</p>
<p>After uninstalling the 'Intel Application Accelerator' my chkdsk finished successfully and defrag seems to be going fine.</p>
<p>Thank goodness for the internet and its wealth of technical solutions!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2006/12/27/windows-crash-multiple_irp_complete_requests-stop-0x00000044/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Bye Bye EDI… Hello ThoughtWorks</title>
		<link>http://jamescrisp.org/2006/12/26/bye-bye-edi-hello-thoughtworks/</link>
		<comments>http://jamescrisp.org/2006/12/26/bye-bye-edi-hello-thoughtworks/#comments</comments>
		<pubDate>Tue, 26 Dec 2006 06:03:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[EDI]]></category>

		<category><![CDATA[ThoughtWorks]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=32</guid>
		<description><![CDATA[Well, after almost four years at EDI (now called CargoWise edi) I am leaving. I finish in the middle of January next year. It has been an interesting time, and I have learnt a lot working with very talented people and from building the framework for a big solution suite (around 4 million lines of [...]]]></description>
			<content:encoded><![CDATA[<p>Well, after almost four years at <a href="http://www.edi.com.au/">EDI</a> (now called <a href="http://www.cargowise.com/"><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_0">CargoWise</span> <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_1">edi</span></a>) I am leaving. I finish in the middle of January next year. It has been an interesting time, and I have learnt a lot working with very talented people and from building the framework for a <a href="http://www.cargowise.com/solutions/enterprise-overview.shtml">big solution suite</a> (around 4 million lines of C# code). I've also had the opportunity to experience the very different joys and pitfalls of product management.</p>
<p>I will be starting at <a href="http://www.thoughtworks.com/"><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_2">ThoughtWorks</span></a> (of <a href="http://nunit.org/"><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_3">NUnit</span></a>, <a href="http://jim.webber.name/">Jim Webber</a> and <a href="http://www.martinfowler.com/">Martin Fowler</a> fame) in the middle of February in the new year. I'm expecting that there will be a lot of new exciting stuff to learn, and a lot of variety in terms of clients and technologies.  <a href="http://www.thoughtworks.com/"><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_4">ThoughtWorks</span></a> are strongly <a href="http://en.wikipedia.org/wiki/Extreme_Programming"><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_5">XP</span></a>, do a lot of development on client sites and even have some <a href="http://www.rubyonrails.org/">Rails</a> projects. The people I have met from <a href="http://www.thoughtworks.com/"><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_6">ThoughtWorks</span></a> have all been very friendly and I look <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-corrected" id="SPELLING_ERROR_7">forward</span> to starting there soon <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2006/12/26/bye-bye-edi-hello-thoughtworks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Thai Ordering and Development Mode vs Production Mode for Rails Apps</title>
		<link>http://jamescrisp.org/2006/11/30/thai-ordering-and-development-mode-vs-production-mode-for-rails-apps/</link>
		<comments>http://jamescrisp.org/2006/11/30/thai-ordering-and-development-mode-vs-production-mode-for-rails-apps/#comments</comments>
		<pubDate>Thu, 30 Nov 2006 11:31:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=29</guid>
		<description><![CDATA[A while back, I wrote a little rails app for Thai food ordering at my work. My colleagues place orders using the system and then bring money to the nominated orderer of the week. Once all orders are in and paid for (this is also tracked in the app), the orderer rings up our favourite [...]]]></description>
			<content:encoded><![CDATA[<p>A while back, I wrote a little rails app for Thai food ordering at my work. My colleagues place orders using the system and then bring money to the nominated <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_0">orderer</span> of the week. Once all orders are in and paid for (this is also tracked in the app), the <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_1">orderer</span> rings up our favourite Thai restaurant (<a href="http://www.laddas.com.au/"><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_2">Laddas</span></a>) and places the order.</p>
<p>I have the app running from fairly cheap shared hosting. At peak times during the ordering, I guess that they'd be 15 or so people simultaneously using the app. We've used it many times without problems. Thus, I was quite surprised and displeased (as were my colleagues), when my hosting account was suspended and we couldn't see what had been ordered this morning. A hasty email to my hosting provider revealed that my account had been suspended due to high load and "ruby flooding". They were kind enough to <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_4">un</span>-suspend my account and we completed the ordering process.</p>
<p>I remembered seeing something about production mode in 'environment.<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_5">rb</span>'. Some googling confirmed my hunch - in development mode, rails apps are much more resource intensive. Caching is not used, and every single file needs to be reloaded every time it is required. After changing my app to production mode, it seemed to run <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-corrected" id="SPELLING_ERROR_6">noticeably</span> faster. <a href="http://here.the.ycros.be/">Michael</a> and I ran 'top' and it looked like each request used less CPU.</p>
<p>So, should you be in a similar situation, this is how to change your app to production mode on fast-<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_7">cgi</span> Apache shared hosting:
<ol>
<li>Confirm that 'database.<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_8">yml</span>' in your <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_9">app's</span> '<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_10">config</span>' directory has a section for production mode, and that it has up to date database connection details.</li>
<li>Edit 'environment.<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_11">rb</span>' in your <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_12">app's</span> '<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_13">config</span>' directory.</li>
<li>Add this line:
<pre>     <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_14">ENV</span>['RAILS_<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_15">ENV</span>'] ||= 'production'</pre>
</li>
<li>Run '<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_16">ps</span> -u [your_user_name]' to find if you have any 'dispatch.<span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_18">fgi</span>' processes running.</li>
<li>If so, kill all of them (they'll restart and use your new <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_19">config</span> settings).</li>
<li>Browse to your app, it should now run faster.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2006/11/30/thai-ordering-and-development-mode-vs-production-mode-for-rails-apps/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails and the initialize() method</title>
		<link>http://jamescrisp.org/2006/09/10/rails-and-the-initialize-method/</link>
		<comments>http://jamescrisp.org/2006/09/10/rails-and-the-initialize-method/#comments</comments>
		<pubDate>Sun, 10 Sep 2006 13:43:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=21</guid>
		<description><![CDATA[I spent a bit of time this weekend on a pet rails project. I came across a strange error when trying to create new records through the application. Editing was working just fine, but creating a new record just seemed to hang.
Breakpoints came to my rescue. In Ruby, they're really handy. You can put a [...]]]></description>
			<content:encoded><![CDATA[<p>I spent a bit of time this weekend on a pet rails project. I came across a strange error when trying to create new records through the application. Editing was working just fine, but creating a new record just seemed to hang.</p>
<p>Breakpoints came to my rescue. In Ruby, they're really handy. You can put a 'breakpoint' call anywhere in your code, and if you have a breakpointer process running (start this with the command 'ruby script/breakpointer'), you jump straight into an interactive ruby console debug session when the breakpoint is hit.</p>
<p>Using the development log and a few breakpoints, I found the that the error was:</p>
<pre>ArgumentError: wrong number of arguments (1 for 0)</pre>
<p>And that it was caused by a line similar to this:</p>
<pre>@order = order.new(params[:order])</pre>
<p>Ie, the controller was creating a new order from the post parameters.</p>
<p>Then all became clear - some time earlier, I'd overridden the initialize() method in the order to default some dates. My code was similar to this:</p>
<pre>def initializesuper()
  if (@new_record)
    self.validFrom = Date.today
    self.validTo = 1.year.from_now.to_date
  end
end</pre>
<p>Great for creating new objects in my tests and console sessions where I always just created the object and then set properties. However, the controller was relying on passing in the post parameters in the constructor.</p>
<p>The solution is to accept any number of params and pass these to the base class:</p>
<pre>def initialize(*params)super(*params)
  if (@new_record)
    self.validFrom = Date.today
    self.validTo = 1.year.from_now.to_date
  end
end</pre>
<p>That way, the order can accept the post parameters in its constructor.</p>
<p>I'm very pleased to say that I can now create new records again!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2006/09/10/rails-and-the-initialize-method/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Learn English using a Blog and Programming Tools!</title>
		<link>http://jamescrisp.org/2006/09/03/learn-english-using-a-blog-and-programming-tools/</link>
		<comments>http://jamescrisp.org/2006/09/03/learn-english-using-a-blog-and-programming-tools/#comments</comments>
		<pubDate>Sun, 03 Sep 2006 12:33:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[English]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=19</guid>
		<description><![CDATA[My fiancee, Soosun, is brushing up on her English skills before going to uni next year. As part of the plan to improve her writing, she's started a blog. Friends and family can write comments on her posts to help improve her written English.
She just wrote a nice article on making kimchi, and I posted [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ohsoosun.blogspot.com/"></a>My fiancee, Soosun, is brushing up on her English skills before going to uni next year. As part of the plan to improve her writing, she's started a <a href="http://ohsoosun.blogspot.com/">blog</a>. Friends and family can write comments on her posts to help improve her written English.</p>
<p>She just wrote a nice article on making kimchi, and I posted a comment containing a copy of her article with English improvements. But how can she tell what I've suggested? The solution we decided to use is kdiff3, a tool I use at work for comparing and merging source code. You can download it <a href="http://sourceforge.net/project/showfiles.php?group_id=58666">here</a>. If you turn word wrap on, it is great for comparing English - shows up the differences beautifully.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2006/09/03/learn-english-using-a-blog-and-programming-tools/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ruby on Rails Hosting, Setup And Migration</title>
		<link>http://jamescrisp.org/2006/08/19/ruby-on-rails-hosting-setup-and-migration/</link>
		<comments>http://jamescrisp.org/2006/08/19/ruby-on-rails-hosting-setup-and-migration/#comments</comments>
		<pubDate>Sat, 19 Aug 2006 08:18:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Ruby / Rails]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=13</guid>
		<description><![CDATA[I've been doing a little rails of late.. Here's a summary of the stuff that I've learnt.
What hosting should I use in Australia for rails?
NOT JUMBA - SEE UPDATED REVIEW BELOW
I'm using jumba (http://www.jumba.com.au). Jumba is very cheap (~$30AUD/year), and they give you shell access, mysql etc. However, there was a period of several weeks [...]]]></description>
			<content:encoded><![CDATA[<p>I've been doing a little rails of late.. Here's a summary of the stuff that I've learnt.</p>
<p><span style="font-weight: bold;">What hosting should I use in Australia for rails?</p>
<p><span style="color: rgb(255, 0, 0);">NOT <span class="blsp-spelling-error" id="SPELLING_ERROR_0">JUMBA</span> - SEE UPDATED REVIEW BELOW</span></p>
<p></span>I'm using <span class="blsp-spelling-error" id="SPELLING_ERROR_1">jumba</span> (http://www.jumba.com.au). <span class="blsp-spelling-error" id="SPELLING_ERROR_2">Jumba</span> is very cheap (~$30<span class="blsp-spelling-error" id="SPELLING_ERROR_3">AUD</span>/year), and they give you shell access, <span class="blsp-spelling-error" id="SPELLING_ERROR_4">mysql</span> etc. However, there was a period of several weeks when they moved me to some server without an install of rails and kept promising to install rails and never did. I finally got them to move me back to their main server which has rails installed. It was a painful process, so I'm not sure if I would recommend them. That being said, things are going OK at the moment, and I've got a few development apps up and running on their service.<span style="font-weight: bold;"><br /></span><br /><span style="color: rgb(255, 0, 0);"><span style="font-weight: bold;">UPDATE 29 March 2006: </span><span class="blsp-spelling-error" id="SPELLING_ERROR_5">Jumba</span> summarily stopped rails support without notice and was rude when I contacted them about it. I would not recommend <span class="blsp-spelling-error" id="SPELLING_ERROR_6">Jumba</span> for web hosting anything - they have frequent down time, server switches and reboots and their low price is made up for by the amount of time you waste. They used to be OK, but no longer. I'm in the market for a new host, will post on how it goes.</span></p>
<p><span style="font-weight: bold;">How to set up rails applications in your home directory (in public_html) under a UNIX/Apache/<span class="blsp-spelling-error" id="SPELLING_ERROR_7">cgi</span>/<span class="blsp-spelling-error" id="SPELLING_ERROR_8">fcgi</span> environment</span><span style="font-weight: bold;"></span>
<ol>
<li>Upload or create your application in your home directory. <span class="blsp-spelling-error" id="SPELLING_ERROR_9">Eg</span>, ~/<span class="blsp-spelling-error" id="SPELLING_ERROR_10">MyRailsApp</span>/</li>
<li>In your public_html directory, create a soft link to the public directory of your app. <span class="blsp-spelling-error" id="SPELLING_ERROR_11">Eg</span>,<br /><span class="blsp-spelling-error" id="SPELLING_ERROR_12">ln</span> -s ~/<span class="blsp-spelling-error" id="SPELLING_ERROR_13">MyRailsApp</span>/public ~/public_html/<span class="blsp-spelling-error" id="SPELLING_ERROR_14">MyRailsApp</span></li>
<li>Make sure dispatch.<span class="blsp-spelling-error" id="SPELLING_ERROR_15">fcgi</span> in the ~/<span class="blsp-spelling-error" id="SPELLING_ERROR_16">MyRailsApp</span>/public directory is executable. If not, <span class="blsp-spelling-error" id="SPELLING_ERROR_17">chmod</span> it a+x.</li>
<li>Confirm that dispatch.<span class="blsp-spelling-error" id="SPELLING_ERROR_18">fcgi</span> has a valid path to ruby on the first line. If you've created this project on another machine, you'll quite possibly need to update the path. The path is often something like '#!/<span class="blsp-spelling-error" id="SPELLING_ERROR_19">usr</span>/local/bin/ruby', but check what it is under your system with 'which ruby'. Special note for <span class="blsp-spelling-error" id="SPELLING_ERROR_20">InstantRails</span> users - you'll always need to update the path when uploading to <span class="blsp-spelling-error" id="SPELLING_ERROR_21">unix</span> hosting, as instant rails uses a windows style path with the slashes the other way around.</li>
<li>Update your 'database.<span class="blsp-spelling-error" id="SPELLING_ERROR_22">yml</span>' file (in the '<span class="blsp-spelling-error" id="SPELLING_ERROR_23">config</span>' directory of your app) with correct database names, user names and passwords.</li>
<li>Run 'dispatch.<span class="blsp-spelling-error" id="SPELLING_ERROR_24">fcgi</span>' (in the 'public' directory of your app). If you see an 'Internal Server Error' message, you know things are going OK. If you've got the path to ruby wrong on the first line, or some other similar problem, you'll find out about it here, where as if you run through the web, you don't get these sorts of problems reported in an easy to understand way.</li>
<li>Check out your running system in the browser (<span class="blsp-spelling-error" id="SPELLING_ERROR_25">eg</span>, browse to http://myhostingcompany.com/MyRailsApp/)</li>
</ol>
<p><span style="font-weight: bold;">Tips for trouble shooting rails errors<br /></span>
<ol>
<li>A good place to start is by reading your logs in the 'log' directory of your rails app. If you're running a development configuration, have a read of 'development.log'.</li>
<li>Try manually running 'dispatch.<span class="blsp-spelling-error" id="SPELLING_ERROR_26">fcgi</span>' in the 'public' directory of your app. If you get an 'Internal Server Error' message printed out on the console, it's probably working <span class="blsp-spelling-error" id="SPELLING_ERROR_27">ok</span>. Alternatives to this are reports of missing files and unable to find ruby - often these aren't shown when browsing to your web site.</li>
</ol>
<p> <span style="font-weight: bold;"><br />Rails problems and solutions</span><span style=""></p>
<p><span style="font-style: italic;">1. Browser and logs show: Application Error - Rails app failed to start properly </span></span><span style="font-style: italic;">" </span><span style="font-style: italic;"><br /></span><br />I got this after my app was moved from one <span class="blsp-spelling-error" id="SPELLING_ERROR_28">unix</span> host to another by my hosting company. I tried heaps of stuff to try and resolve this. Eventually I created a brand new dummy project on the <span class="blsp-spelling-error" id="SPELLING_ERROR_29">unix</span> host called 'Test' and Test worked fine from the browser. I then tried my original project again and suddenly it worked fine! It has been working fine since. I can only imagine that there was some sort of problem in temporary files or similar which got flushed. No good explanation for this currently.<span style="font-style: italic;"><br /></span><span style="font-size:85%;"></p>
<p></span><span style="font-style: italic;">2. in `start_engine': undefined method `add_path' for Controllers:Module (<span class="blsp-spelling-error" id="SPELLING_ERROR_30">NoMethodError</span>)</p>
<p></span>I got this one when migrating a project from rails 1.1 to a later version of rails. The solution is to force update your rails engines:</p>
<p><span style=";font-family:courier new;font-size:85%;"  >script/<span class="blsp-spelling-error" id="SPELLING_ERROR_31">plugin</span> source http://svn.rails-engines.org/plugins</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;"  >script/<span class="blsp-spelling-error" id="SPELLING_ERROR_32">plugin</span> install engines --force</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;"  >script/<span class="blsp-spelling-error" id="SPELLING_ERROR_33">plugin</span> install <span class="blsp-spelling-error" id="SPELLING_ERROR_34">login</span>_engine --force</span></p>
<p><span style="font-style: italic;">3. My app works fine if there is a trailing slash on the <span class="blsp-spelling-error" id="SPELLING_ERROR_35">url</span>. Otherwise, I get a 'Bad Request' error page. <span class="blsp-spelling-error" id="SPELLING_ERROR_36">Eg</span>, 'http://myhost.com/myapp/' works, but 'http://myhost.com/myapp' does not work.</p>
<p></span>Add a <span class="blsp-spelling-error" id="SPELLING_ERROR_37">RewriteRule</span> to the .<span class="blsp-spelling-error" id="SPELLING_ERROR_38">htaccess</span> file in your application's public folder:<span style="font-style: italic;"><br /></span>    <span class="blsp-spelling-error" id="SPELLING_ERROR_39">RewriteRule</span> ^.*<span class="blsp-spelling-error" id="SPELLING_ERROR_40">myapp</span>$    http://%{HTTP_HOST}/myapp/ [R=301,L]</p>
<p>My basic .<span class="blsp-spelling-error" id="SPELLING_ERROR_41">htaccess</span> rewrites are as follows:<br /><span style=";font-family:courier new;font-size:85%;"  ><span class="blsp-spelling-error" id="SPELLING_ERROR_42">RewriteEngine</span> On</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;"  ><span class="blsp-spelling-error" id="SPELLING_ERROR_43">RewriteRule</span> ^.*<span class="blsp-spelling-error" id="SPELLING_ERROR_44">myapp</span>$ http://%{HTTP_HOST}/myapp/ [R=301,L]</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;"  ><span class="blsp-spelling-error" id="SPELLING_ERROR_45">RewriteCond</span> %{REQUEST_<span class="blsp-spelling-error" id="SPELLING_ERROR_46">FILENAME</span>} !-f</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;"  ><span class="blsp-spelling-error" id="SPELLING_ERROR_47">RewriteRule</span> ^(.*)$ dispatch.<span class="blsp-spelling-error" id="SPELLING_ERROR_48">fcgi</span> [<span class="blsp-spelling-error" id="SPELLING_ERROR_49">QSA</span>,L]</span></p>
<p>I tried removing the <span class="blsp-spelling-error" id="SPELLING_ERROR_50">RewriteCond</span> !-f, and my pages lost their styles. I think the condition allows the rails framework to load .<span class="blsp-spelling-error" id="SPELLING_ERROR_51">css</span> files directly without having the requests go through dispatch.<span class="blsp-spelling-error" id="SPELLING_ERROR_52">fcgi</span>.<br /><span style="font-weight: bold;"></span></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2006/08/19/ruby-on-rails-hosting-setup-and-migration/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Review: UML Distilled</title>
		<link>http://jamescrisp.org/2006/05/23/book-review-uml-distilled/</link>
		<comments>http://jamescrisp.org/2006/05/23/book-review-uml-distilled/#comments</comments>
		<pubDate>Wed, 24 May 2006 01:30:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=7</guid>
		<description><![CDATA[UML Distilled: A brief guide to the standard object modelling language(3rd Edition)by Martin Fowler
UML Distilled is good. It is written carefully and concisely and has been heavily revised to cover UML 2. It is a opinionated book - it presents Martin Fowler's view of UML. This is a good thing. Fowler concentrates on the parts [...]]]></description>
			<content:encoded><![CDATA[<p>UML Distilled: A brief guide to the standard object modelling language<br />(3rd Edition)<br />by Martin Fowler</p>
<p>UML Distilled is good. It is written carefully and concisely and has been heavily revised to cover UML 2. It is a opinionated book - it presents Martin Fowler's view of UML. This is a good thing. Fowler concentrates on the parts of UML that he has found widely used in the industry, and the most useful in his own work. Fowler is not bound by the UML specification, he also describes "non-normative" diagrams (ie, variations on UML which are not standard but widely used). Fowler often provides his own view on a particular diagram or component. For example, I've often wondered when to use aggregation rather than association in a class diagram. Fowler cleared this up for me:</p>
<p>"Aggregation is strictly meaningless; as a result, I recommend that you ignore it in your own diagrams. If you see it in other people's diagrams, you'll need to dig deeper to find out what they mean by it. Different authors and teams use it for very different purposes."</p>
<p>UML Distilled starts with an introduction about UML's history and aims, and then a rapid look at different development methodologies and where to fit UML into them.</p>
<p>The core of the book covers the following diagrams/specs:</p>
<p>Class Diagrams<br />Sequence Diagrams<br />Object Diagrams<br />Package Diagrams<br />Deployment Diagrams<br />Use Cases<br />State Machine Diagrams<br />Activity Diagrams<br />Communication Diagrams<br />Composite Structures<br />Component Diagrams<br />Collaborations<br />Interaction Overview Diagrams<br />Timing Diagrams</p>
<p>Class diagrams and sequence diagrams are covered in detail, the other diagrams more briefly. The book is quite short, but gives enough information on each topic to allow you to understand and draw the diagrams. At the end of each chapter, there is a helpful "where to find out more" section and a "when to use this type of diagram" section.</p>
<p>There is also an appendix at the end of the book on changes between various versions of UML.</p>
<p>The book is surprisingly easy to read. Fowler's style is clear and friendly and examples are well chosen.</p>
<p>My only complaint is that perhaps the book could have been a little longer to allow a bit more detail on some of the diagram types. I would have liked to have read a little bit more on object diagrams in particular.</p>
<p>I'd recommend the book to anyone who wants a rapid and concise introduction to or revision of UML 2.</p>
<p>Rating: 9/10</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2006/05/23/book-review-uml-distilled/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Review: My Job Went to India, 52 Ways to Save Your Job</title>
		<link>http://jamescrisp.org/2006/05/20/book-review-my-job-went-to-india-52-ways-to-save-your-job/</link>
		<comments>http://jamescrisp.org/2006/05/20/book-review-my-job-went-to-india-52-ways-to-save-your-job/#comments</comments>
		<pubDate>Sun, 21 May 2006 00:36:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
		
		<category><![CDATA[Book Reviews]]></category>

		<category><![CDATA[Soft Skills and Mind Hacks]]></category>

		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/wordpress/?p=4</guid>
		<description><![CDATA[Full Title: My Job Went to India (And All I Got Was This Lousy Book), 52 Ways to Save your Job
Author: Chad Fowler of the Pragmatic Programmers
185 pages, Paperback
An interesting book written by Chad Fowler, who spent 1.5 years in India hiring and managing an outsourced team of developers. The book's main focus is on [...]]]></description>
			<content:encoded><![CDATA[<p>Full Title: My Job Went to India (And All I Got Was This Lousy Book), 52 Ways to Save your Job</p>
<p>Author: Chad Fowler of the Pragmatic Programmers</p>
<p>185 pages, Paperback</p>
<p>An interesting book written by Chad Fowler, who spent 1.5 years in India hiring and managing an outsourced team of developers. The book's main focus is on how you can make yourself as, a developer, more valuable to your company / community so that your job is not outsourced. There are quite a lot of valuable and interesting ideas in the book for professional development, and "getting your name out there". The book also gives the reader some idea of what development is like in India, some tips and the pluses and minuses of outsourcing.</p>
<p>The style of the book is conversational, and easy to read. I finished it in 2 days. I'd recommend it to developers wondering about outsourcing and looking for some tips on professional development.</p>
<p>Rating: 8/10</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2006/05/20/book-review-my-job-went-to-india-52-ways-to-save-your-job/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
