<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>James Crisp » Technical</title>
	
	<link>http://jamescrisp.org</link>
	<description>C#, .NET, Ruby, Rails, book reviews, mind hacks, Wing Chun and the occasional personal bit.</description>
	<lastBuildDate>Mon, 26 Nov 2012 23:23:36 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<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>Talk tonight: Responsive Layout with HTML5</title>
		<link>http://jamescrisp.org/2012/11/27/talk-tonight-responsive-layout-with-html5/</link>
		<comments>http://jamescrisp.org/2012/11/27/talk-tonight-responsive-layout-with-html5/#comments</comments>
		<pubDate>Mon, 26 Nov 2012 23:08:58 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[ALT.NET]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=772</guid>
		<description><![CDATA[I'll be giving a talk at Sydney ALT.NET tonight: Want to build a web application which dynamically changes layout to best suit the client, be it mobile, tablet or desktop with the same HTML? Fun times with HTML5, Bootstrap, HAML and Sass. You'll get to see it in action, and the code behind the magic. [...]]]></description>
				<content:encoded><![CDATA[<p>I'll be giving a talk at <a href="http://sydney.ozalt.net/">Sydney ALT.NET</a> tonight:</p>
<blockquote><p><i>Want to build a web application which dynamically changes layout to best suit the client, be it mobile, tablet or desktop with the same HTML? Fun times with HTML5, Bootstrap, HAML and Sass. You'll get to see it in action, and the code behind the magic.</i></p></blockquote>
<p>From 6pm at ThoughtWorks Sydney office on Pitt St. Remember to RSVP on the <a href="http://sydney.ozalt.net/">Sydney ALT.NET site</a> to help with catering. See you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2012/11/27/talk-tonight-responsive-layout-with-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VPS Performance Comparison and Benchmarking</title>
		<link>http://jamescrisp.org/2012/06/20/vps-performance-comparison-and-benchmarking/</link>
		<comments>http://jamescrisp.org/2012/06/20/vps-performance-comparison-and-benchmarking/#comments</comments>
		<pubDate>Wed, 20 Jun 2012 05:35:09 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=700</guid>
		<description><![CDATA[What VPS / cloud instance provider gives you the best bang for buck for a small linux server? I've been focusing on evaluating providers at the low cost end, and reasonable latency to Australia - Linode Tokyo, Octopus Australia, RailsPlayground USA and Amazon Singapore. From the tech specs on a VPS, most providers look similar. [...]]]></description>
				<content:encoded><![CDATA[<p>What VPS / cloud instance provider gives you the best bang for buck for a small linux server? I've been focusing on evaluating providers at the low cost end, and reasonable latency to Australia - Linode Tokyo, Octopus Australia, RailsPlayground USA and Amazon Singapore. From the tech specs on a VPS, most providers look similar. However, when you have an instance, you often find huge variation in performance due to contention for CPU and disk on the node. For a simple test, I ran a small ruby script on each server every 20 minutes on cron, and logged the results to a CSV file over the same 5 days.</p>
<p>Here is the script:</p>
<pre>start = Time.now

`man ls`
`ls /`

disk_time = Time.now - start

start = Time.now

(1..200000).each { |i| i*i/3.52345*i*i*i%34 }

cpu_time = Time.now - start

total = disk_time + cpu_time
puts "#{total},#{disk_time},#{cpu_time},#{start.strftime('%Y-%m-%d')},#{start.strftime('%H:%M:%S')}"</pre>
<p>It uses ls and man to test wait for disk and then some made up maths to test the CPU. It's not perfect but gives a good indication of performance.</p>
<p><b><i>Results</i></b><br />
All times are in seconds, and you can download the full data to get a better picture. I've provided a summary and notes for each provider below.</p>
<p><a href="http://www.linode.com/"><strong>Linde 512mb Tokyo (Zen)</strong></a></p>
<table>
<tr>
<th>&nbsp;</th>
<th>Average</th>
<th>Max</th>
</tr>
<tr>
<th>Total time</th>
<td>0.81</td>
<td>1.74</td>
</tr>
<tr>
<th>Disk</th>
<td>0.03</td>
<td>0.13</td>
</tr>
<tr>
<th>CPU</th>
<td>0.78</td>
<td>1.63</td>
</tr>
</table>
<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2012/06/linode_tokyo.xls'>Full Results</a></p>
<p>This is my second Linode VPS. I asked to be moved to a different node as the first one started fast when I got it but performance degraded (due to contention on the node?) within a few days. Nothing else is running on the VPS besides the script. Overall this is consistent, good performance in both CPU and disk. Latency to this VPS is around ~130ms from my ADSL in Sydney.</p>
<p><a href="http://octopus.com.au/"><strong>Octopus 650mb Australia (VMWare)</strong></a></p>
<table>
<tr>
<th>&nbsp;</th>
<th>Average</th>
<th>Max</th>
</tr>
<tr>
<th>Total time</th>
<td>0.74</td>
<td>3.40</td>
</tr>
<tr>
<th>Disk</th>
<td>0.19</td>
<td>2.88</td>
</tr>
<tr>
<th>CPU</th>
<td>0.54</td>
<td>1.08</td>
</tr>
</table>
<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2012/06/octopus.xls'>Full Results</a></p>
<p>Octopus is running a site for me with a significant cron job on the hour. I've therefore removed results collected on the hour. Despite running my live site, Octopus has the fastest average performance of all VPS tested. The higher max time could have been caused by load on my site. Octopus costs a bit more but is hosted in Australia so has very low latency of around 20ms from my ADSL in Sydney.</p>
<p><a href="http://aws.amazon.com/ec2/"><strong>Amazon Small Instance 1.7gb Singapore (Zen)</strong></a></p>
<table>
<tr>
<th>&nbsp;</th>
<th>Average</th>
<th>Max</th>
</tr>
<tr>
<th>Total time</th>
<td>1.25</td>
<td>2.42</td>
</tr>
<tr>
<th>Disk</th>
<td>0.20</td>
<td>0.40</td>
</tr>
<tr>
<th>CPU</th>
<td>1.04</td>
<td>2.03</td>
</tr>
</table>
<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2012/06/amazon_singapore.xls'>Full Results</a></p>
<p>Amazon EC2 Small instances are now in the same ballpark cost as small VPS instances, when you go for high usage reserved. Many people think that EC2 disk is poor. However, from my tests (and experience) it is not super fast, but it is consistent and reliable. Amazon is also very generous with memory and provides other benefits like free transfer to S3. Where it falls down is processor speed, which, although fairly consistent, is about 50% slower than Linode and Octopus. Latency from Sydney ADSL is around 120ms.</p>
<p><a href="http://railsplayground.com/plans-products/vps/"><strong>Rails Playground 640mb USA (Virtuozzo)</strong></a></p>
<table>
<tr>
<th>&nbsp;</th>
<th>Average</th>
<th>Max</th>
</tr>
<tr>
<th>Total time</th>
<td>3.53</td>
<td>24.12</td>
</tr>
<tr>
<th>Disk</th>
<td>2.44</td>
<td>23.42</td>
</tr>
<tr>
<th>CPU</th>
<td>1.09</td>
<td>2.66</td>
</tr>
</table>
<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2012/06/rails_playground.xls'>Full Results</a></p>
<p>My RailsPlayground VPS is running various services and sites for me but none of them are high load. As you can see, the CPU performance is similar to Amazon and doesn't vary too much. The problem is disk which varies hugely and can sometimes lead to unresponsive sites and services while waiting for IO. Latency from Sydney ADSL is around 200ms.</p>
<p><i><b>Conclusion</i></b><br />
If you want a fast VPS with low latency in Australia and are willing to pay a bit more than the other providers listed, Octopus VPS will serve you well.</p>
<p>For lots of memory but slower CPU, Amazon small instance will be good.</p>
<p>For faster CPU but less memory, Linode is your best choice.</p>
<p>It's worth testing out any new VPS and keeping an eye on performance over time. Contention on your node could change dramatically without you being aware of it, dramatically impacting performance of your VPS.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2012/06/20/vps-performance-comparison-and-benchmarking/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Jetstar Review: Booking a holiday package</title>
		<link>http://jamescrisp.org/2011/06/11/jetstar-review-booking-a-holiday-package/</link>
		<comments>http://jamescrisp.org/2011/06/11/jetstar-review-booking-a-holiday-package/#comments</comments>
		<pubDate>Sat, 11 Jun 2011 04:47:25 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=572</guid>
		<description><![CDATA[With some holiday leave coming up, my wife and I decided to go to Queensland for a warm break from the Sydney winter. After a little online research into Virgin and Jetstar packages, and booking directly, it was clear that going with a Jetstar package for the flight and hotel was several hundred dollars cheaper. [...]]]></description>
				<content:encoded><![CDATA[<p>With some holiday leave coming up, my wife and I decided to go to Queensland for a warm break from the Sydney winter. After a little online research into Virgin and Jetstar packages, and booking directly, it was clear that going with a Jetstar package for the flight and hotel was several hundred dollars cheaper. The hotel on offer also looked quite good and only had availability for our dates when booked through Jetstar.</p>
<p><strong>Tues 7 June</strong><br />
Went to the <a href="http://www.jetstar.com" rel="nofollow">Jetstar site</a>. The first time I tried entering our dates for the search, I got a message about the site being overloaded and please try again. I did so, and got to the next page, allowing me to customise flight times and choose accommodation options. The hotel we wanted to stay at had the same room type listed 3 times, at different prices. I had called Jetstar about this earlier in the day as I'd seen it, and been confused, when researching prices earlier. They had explained that it was the same room type - just if the cheapest price for the room type was already full, you would have to buy the next one up and so on. Following this advice, I chose the cheapest price for the room type offered. </p>
<p>I then tried to click the 'Reviews and Information' link which had worked earlier when I'd been doing the price comparison. This time, I got an exception message:</p>
<p><a href="http://jamescrisp.org/wordpress/wp-content/uploads/2011/06/jetstar_error.png"><img src="http://jamescrisp.org/wordpress/wp-content/uploads/2011/06/jetstar_error-300x173.png" alt="" title="jetstar_error" width="300" height="173" class="alignleft size-medium wp-image-574" style="float:none;"/></a><br />
For the technical minded, you can see that the link from the package configuration page was faulty and did not include a 'hotelId' (bug?). Next, the hotel information page did not check the input parameters at all (bug and security risk) and exploded. Lastly, you can see that the Jetstar site has not been configured for production error messages. Instead, a developer error message was displayed which exposes implementation and technology details to the casual observer (security risk and poor user experience).</p>
<p>Somewhat concerned, I continued with the booking process. Choosing flights worked well, except I did wonder why one of the flight choices was listed as 4 hour duration, but left at 7am and arrived at 10am:</p>
<p><a href="http://jamescrisp.org/wordpress/wp-content/uploads/2011/06/jetstar_flight_time.png"><img src="http://jamescrisp.org/wordpress/wp-content/uploads/2011/06/jetstar_flight_time-300x92.png" alt="" title="jetstar_flight_time" width="300" height="92" class="alignleft size-medium wp-image-582"  style="float:none;"/></a><br />
We next entered personal details for me and my wife. We had to try several times to submit the form as there must have been validation rules that our data was not meeting, but no error messages were displayed to help us. We fiddled around with the details we'd entered a bit (different formats for phone numbers etc), and then it finally worked.</p>
<p>Transitioning to the next page was very slow, but eventually came up with a chance to choose seats and travel insurance. My wife was sitting with me at the computer and we decided to choose seats. It was certainly not clear that we would have to pay extra for this. So I went ahead and chose some nice seats near the front of the plane (quick exit seats they were called) and then noticed that this would add an extra ~$64 on to the holiday cost! Realising our mistake, we chose regular seats a little further back. This was still an extra $16 on to the cost of the holiday. We tried everything we could think of to try and de-select our seat choices but could not find a way to do so that would actually stick (you could de-select temporarily but this could not be saved). Somewhat annoyed, we continued with the booking.</p>
<p>Next I entered my credit card details. It turned out there was an extra $30 booking and service charge that suddenly appeared at that point. Not happy but keen to finish the booking process, we next hit the pay button. The site took a while to respond and then reloaded the payment page, showing that there was a balance of $-907.40 with a proceed button below it. Quite a mystery. Had my credit card been charged? Had anything been booked? What did the mysterious $-907.40 mean?</p>
<p>I rang the call centre. Unfortunately it was either overloaded or down and I couldn't even get to the "Press 1 for English..." prompt. I waited 15 minutes and rang again. I left the phone on speaker and went on with other things. I was on hold for 54 minutes before I gave up and went to bed. </p>
<p><strong>Wed 8 June</strong><br />
In the morning, I range the call centre again, and got through in about 20 minutes to the reservations section. I explained the situation to the customer service person and she found my booking. It turned out that flights were booked, the hotel was not booked, and my itinerary was not sent. I explained which hotel was meant to be booked and she went to talk to her supervisor. I was on hold for a further 30 minutes or so with a few other brief questions during this time. She was able to send me the flight itinerary without the hotel which she did. She was unable to help with the hotel booking, but sent an internal request to the holidays section and said they would call me back within 24-48 hours to help with the hotel booking. I asked if I had any assurance that the hotel was booked. She said I didn't have any assurance. I asked if there was any way to make this faster, as I needed to know if I should book my own accommodation. She sounded annoyed and said that there was nothing she could do, it was a different section of the business and she couldn't help me further, just wait for the phone call in 24-48 hours. I did receive a copy of the itinerary for flights without hotel within 24 hours as promised. Meanwhile I had tweeted to @JetstarAirways about the experience so far, and they asked for my booking reference via DM to expedite things.</p>
<p><strong>Thurs 9 June</strong><br />
Finally received a phone call from Jetstar holiday section. The guy said that he had looked into the case and sorted out the hotel booking. Great news! I asked if he could do anything about the $16 seat booking charge from earlier, but he said that it was clearly explained on the site, and he couldn't do anything about it. He promised that the complete itinerary would arrive including the hotel booking within 24 hours and I gave him my email address (not sure why they didn't have it from earlier, I'd already received the flight itinerary via email).</p>
<p><strong>Fri 10 June</strong><br />
Waiting for itinerary. It did not arrive.</p>
<p><strong>Sat 11 June</strong><br />
Wondering what had happened, I rang the call centre again. This time, I didn't go on hold at all and got straight through to a helpful lady that confirmed my email address - it had been entered wrongly. That was probably why I hadn't got an email yet. She fixed the typo in my email address, and I received the complete and correct itinerary within 10 minutes. The booking process was now complete!</p>
<p><strong>Conclusion</strong><br />
A transaction I had expected to take about 20 minutes booking through the site took about 4 days from start to end, including about 2 hours of time on the phone to the call centre. The Jetstar price was still good compared with other options, but the unexpected charges of $16 for choosing seats and $30 for booking fee were a major turn off. The bugs in the site (especially the validation of personal details without showing error messages) must lose many potential customers. The failure of the purchase process which left the customer confused but charged without services being booked was a major issue. The call centre delays were a time waster and the silo-ed nature of the business between flights and holidays made solving problems slower and harder. Jetstar's twitter account was potentially a help in resolving problems.</p>
<p><strong>Post-Holiday Update</strong><br />
Happy to say that the flights and hotel worked well after all the booking was sorted out. Jetstar also upgraded us to a better room at the hotel which was a nice touch.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2011/06/11/jetstar-review-booking-a-holiday-package/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Automated Testing and the Test Pyramid</title>
		<link>http://jamescrisp.org/2011/05/30/automated-testing-and-the-test-pyramid/</link>
		<comments>http://jamescrisp.org/2011/05/30/automated-testing-and-the-test-pyramid/#comments</comments>
		<pubDate>Mon, 30 May 2011 06:11:20 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=468</guid>
		<description><![CDATA[Why Do Automated Testing? Before digging into a testing approach, lets talk about key reasons to do automated testing: Rapid regression testing to allow systems/applications to continue to change and improve over time without long "testing" phases at the end of each development cycle Finding defects and problems earlier and faster especially when tests can [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Why Do Automated Testing?</strong><br />
Before digging into a testing approach, lets talk about key reasons to do automated testing:</p>
<ul>
<li>Rapid regression testing to allow systems/applications to continue to change and improve over time without long "testing" phases at the end of each development cycle</li>
<li>Finding defects and problems earlier and faster especially when tests can be run on developer machines, and as part of a build on a CI server</li>
<li>Ensure external integration points are working and continue to work as expected</li>
<li>Ensure the user can interact with the system as expected</li>
<li>Help debugging / writing / designing code</li>
<li>Help specify the behaviour of the system</li>
</ul>
<p>Overall, with automated testing we are aiming for increased project delivery speed with built in quality.</p>
<p><strong>Levels of Automated Tests</strong><br />
Automated tests come in a variety of different flavours, with different costs and benefits. They are sometimes called by different names by different people. For the purposes of clarity, let's define the levels as follows:</p>
<p><em>Acceptance Tests</em><br />
Highest level tests which treat the application as a black box. For an application with a user interface, they are tests which end up clicking buttons and entering text in fields. These tests are brittle (easily broken by intended user interface changes), give the most false negative breaks, expensive to write and expensive to maintain. But they can be written at a level of detail that is useful for business stakeholders to read, and are highly effective at ensuring the system is working from an end user perspective.</p>
<p><em>Integration Tests</em><br />
Code which tests integration points for the system. They ensure that integration points are up and running, and that communication formats and channels are working as expected. Integration tests are generally fairly easy to write but maintenance can be time consuming when integration points are shared or under active development themselves. However, they are vital for ensuring that dependencies of the system you are building continue to work as you expect.  These tests rarely give false negatives, run faster than acceptance tests but much slower than unit tests.</p>
<p><em>Unit Tests</em><br />
Tests which are fine grained, extremely fast and test behaviour of a single class (or perhaps just a few related classes). They do not hit any external integration points. [This is not the most pure definition of unit tests, but for the purposes of this post, we do not need to break this category down further]. As unit tests are fast to write, easy to maintain (when they focus on behaviour rather than implementation) and run very quickly, they are effective for testing boundary conditions and all possible conditions and code branches. </p>
<p><strong>Automated Test Strategy</strong><br />
<a href="http://jamescrisp.org/wordpress/wp-content/uploads/2011/05/test_pyramid.gif"><img src="http://jamescrisp.org/wordpress/wp-content/uploads/2011/05/test_pyramid-300x218.gif" alt="" title="Test Pyramid" width="300" height="218" class="alignleft size-medium wp-image-472" /></a>An important part of test strategy is to decide the focus of each type of test and the testing mix. I'd generally recommend a testing mix with a majority of unit tests, some integration tests, and a small number of acceptance tests. In the test pyramid visualisation, I've included percentages of the number of tests, but this is just to give an idea of rough test mix breakdown.</p>
<p>So, why choose this sort of mix of tests? This mix allows you to cover alternative code paths and boundary conditions in tests that run very fast at the unit level. There are many combinations of these and they need to be easily maintained. Hence unit tests fit the bill nicely. </p>
<p>Integration tests are a slower and harder to maintain, so it's better to have less of them, and target them specifically to cover off the risks of system integration points. It would be inefficient to test your system logic with integration tests, since they would be slow, and you would not know if the failure was from your code or from the integration point. </p>
<p>Finally, acceptance tests are the most expensive tests to write, run and maintain. This is why it is important to minimise the number of these, and push down as much testing as possible to lower levels. They give a great view of "Is the System working?", but they are very inefficient for testing boundary conditions, all code paths etc. Generally, they are best for testing scenarios. For example, a scenario might be: Student logs in to the portal, chooses subjects for the semester in a multi-step wizard, then logs out. It would be best to avoid fine grained acceptance tests - they would cost more than the value they would add - ie, it would be better they had never been written. An example of such a test could be: Student chooses a subject and it is removed from the list of subjects available to be chosen. Or student enters an invalid subject code and is shown the error "Please choose a valid subject code". Both of these would be best pushed down to a unit test level. If this is not possible, it would be best to include them in a larger scenario to avoid the set up overhead (eg, for the error message test set up, it may be necessary to log in and enter data to get to step 3 of wizard before you can check if an invalid subject code error message is displayed). </p>
<p>With acceptance tests, I'd recommend writing the minimum up front, just covering the happy paths and a few major unhappy paths. If defects come to light from exploratory testing, then discover how they slipped through the testing net. Why weren't they covered by unit and integration tests, and could they be? If you have tried everything you can think of to improve lower levels of testing, and are still having too many defects creeping through, then consider upping your acceptance coverage. However, keep the cost/benefit analysis in mind. You want your tests to make your team go faster, and an overzealous acceptance suite can eat into the team's time significantly with maintenance and much increased cost of change. Finally, keep in mind there is a manual testing option. Manual testing needs to be minimised, but if it is 3 minutes to test something manually (eg, checking something shows up in a minor external system) or a week to automate the test, you're probably going to be better off keeping a manual test or two around. </p>
<p><strong>Team Roles and Tests</strong><br />
Ideally it would be great to have developers who were interested in testing and the business, testers who knew how to code and the business context, and BAs who were interested in testing and coding too. Ie, a team of people who could do each role in a pinch, but were more specialised in a particular area. Unfortunately this is pretty rare outside of very small companies with small teams. In a highly differentiated team, with dedicated Developers, BAs and QAs, this generally ends up with developers writing and maintaining unit tests, doing a lot of integration tests and helping out with acceptance tests. QAs generally write some integration tests and look after writing and maintaining acceptance tests with help from developers. BAs are sometimes involved in the text side of writing acceptance tests.</p>
<p><strong>English Language Text Files &#038; BDD</strong><br />
There are many tools that bill themselves as Behaviour Driven Development (BDD) testing tools which are based on having features written in formulaic English, backed by regular expressions matching chunks of text then linked to procedural steps. Often using such a tools is considered BDD and a good thing in a blanket way.</p>
<p>Lets take a step back. BDD is about specifying behaviour, rather than implementation and encouraging collaboration between roles. All good things. BDD can be done in NUnit, JUnit, RSpec etc. There is no requirement in BDD that tests are written in formulaic English with a Given-When-Then format. The converse is also true - if you write tests which are about implementation using an English language BDD framework, you are not doing BDD.</p>
<p>Using an English language layer on top of normal code is expensive. It is slower to write tests (you need to edit two files every test, and get your matching regexes right), harder to debug, refactor and maintain (tracing test execution between feature text, regex and steps is time consuming and there's less IDE support), and less scalable as suites grow large (most of these frameworks use steps which are isolated procedures with global variables for communication and no object oriented abstraction or packaging). Also for many people who are used to reading code, the English language layer is less concise and slower to read than code for specifying behaviour.</p>
<p>What do you get from an English language layer? It means that less technical people (eg, business sponsor and BAs) can easily read tests, and maybe just possibly, even write the English language half of tests.</p>
<p>It is worth carefully weighing up the costs and benefits in your situation before deciding if you want to fork out the extra development and maintenance cost for an English language layer. Unit tests and integration tests are not likely to pay dividends having an English language layer - non-technical people would not be reading or writing these tests. Acceptance tests are potentially the sweet spot. If your team's business representative(s) or BA(s) are keen to write the English language side of the tests, while keeping in mind the granularity of a scenario style approach, you could be on to a winner. Writing these tests could really help bring the different roles on the team together and come to a common understanding. </p>
<p>On the other hand, if your team's business sponsor(s) are too busy or not interested in sitting down writing tests in text files, and the BAs are not interested or have their hands full elsewhere, then there are few real benefits in having the English language layer and the same costs apply. </p>
<p>A middle ground is to generate readable reports from code based test frameworks. With this approach you get a lot of the benefits with much less cost. Business people and BAs cannot write tests unaided, but they can read what tests ran (a specification of the system) in clear English.</p>
<p><strong> Traceability from Requirements</strong><br />
A concept that most commonly comes up at companies doing highly traditional SDLCs is traceability from requirements all the way to code and tests. Clearcase and some of the TFS tools are the children of this idea.  Acceptance testing tools are often misused to automate far too many fine grained tests to attempt to prove that there is traceability from requirements.</p>
<p>A friend was explaining his area of expertise around proof of program correctness for safety critical systems where many peoples' lives depend on a system. I totally agree that in this small subset of systems, it is vital to specify the system exactly and mathematically and prove it is correct in all cases. </p>
<p>However, the majority of business systems do not need to be specified in such detail or with such accuracy. Most business systems which people attempt to specify up front are written in natural language which is notorious for inexactitude and differing interpretations. As the system is written, many of these so called requirements change as the business changes, technical constraints are realised, and as people see the system working, they realise it should work differently. </p>
<p>Is traceability back to outdated requirements useful? Should people spend time updating these "requirements" to keep them in sync with the real system development? I would say a resounding NO. There is no point in this. If the system is already built, these artefacts have realised their value and their time is over. If documentation is required for other purposes such as supporting the system, then it is worth writing targeted documents with that audience and purpose in mind. </p>
<p>On the testing front, this traceability drive can lead to vast numbers of fine grained acceptance tests (eg, one for each requirement) being written in an English-language BDD test framework. This approach is naive and leads to the problems we have covered earlier.</p>
<p><strong>Recent Experiences</strong><br />
On a project a couple of years ago which had a test square rather than a pyramid (hundreds of acceptance tests that ran in a browser), it took 2 people full time (usually a dev and a QA) to keep the acceptance suite up and running. Developers generally left updating the acceptance tests to the dedicated QA/Dev, as it took around an hour to run the full test suite, and had many false negative failures to chase up (was the failure due to an intended screen change, an integration point being down, or a real issue in the software?). The test suite was in Fitnesse for .NET, which was hard to debug and use, and had its own little wiki style version control that didn't fit in well with the source version control system. The acceptance test suite was red the majority of the time due to false negatives, so it was hard to know if a build was really working or not. To get a green build would take luck and several tries nursing the build through. I would count this as a prime example of an anti-pattern in automated test strategy, where there were far too many fine grained acceptance tests which took far too much effort to write and maintain.</p>
<p>On my last 3 projects, taking the test pyramid approach, we had a small number of acceptance tests which were scenario based, covered the happy paths and a few unhappy paths. On these projects, tests ran in just a few minutes, so could be run on developer machines before check in. The maintenance overhead of updating tests could be included in the development of a story rather than requiring full time people dedicated to resolving issues. Acceptance builds had few false negatives and hence were much more reliable indicators. We also chose tools which were code/text-file based, and could be checked into version control with the rest of the source code. The resulting systems in production had low defect rates.</p>
<p><b>Conclusion</b><br />
Some of the ideas in this post go against the prevailing testing fashions of the moment. However, rather than following fashion, let's look at the costs and benefits of the ideas and tools we employ. The aim of automated testing is to increase throughput on the project (during growth and maintenance) while building in sufficient quality. Anything that costs more to build and maintain than the value it provides should be changed or dropped.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2011/05/30/automated-testing-and-the-test-pyramid/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Rails Refactor is now a Gem!</title>
		<link>http://jamescrisp.org/2011/05/04/rails-refactor-is-now-a-gem/</link>
		<comments>http://jamescrisp.org/2011/05/04/rails-refactor-is-now-a-gem/#comments</comments>
		<pubDate>Wed, 04 May 2011 06:09:35 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=452</guid>
		<description><![CDATA[Rails Refactor, a small command line tool to make rails refactoring more fun, is now available as a gem. To use: gem install rails_refactor More info available on github.]]></description>
				<content:encoded><![CDATA[<p>Rails Refactor, a small command line tool to make rails refactoring more fun, is now available as a gem. To use:<br />
<code>gem install rails_refactor</code></p>
<p>More info available on <a href="https://github.com/jcrisp/rails_refactor">github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2011/05/04/rails-refactor-is-now-a-gem/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VIM is Sydney Rails Devs’ Favourite Editor</title>
		<link>http://jamescrisp.org/2011/02/08/vim-is-rails-devs-favourite-editor/</link>
		<comments>http://jamescrisp.org/2011/02/08/vim-is-rails-devs-favourite-editor/#comments</comments>
		<pubDate>Tue, 08 Feb 2011 12:30:56 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=438</guid>
		<description><![CDATA[Outstanding news! As part of the rails refactor talk at RORO (Sydney Rails Group) tonight (great evening by the way!), I asked for a show of hands on people's favoured editors. I was amazed to discover the vim has edged out TextMate with just over half of the people at the group using it as [...]]]></description>
				<content:encoded><![CDATA[<p>Outstanding news! As part of the <a href="http://jamescrisp.org/2011/02/01/short-talk-on-rails_refactor-at-rails-group/">rails refactor</a> talk at RORO (Sydney Rails Group) tonight (great evening by the way!), I asked for a show of hands on people's favoured editors. I was amazed to discover the vim has edged out TextMate with just over half of the people at the group using it as their editor of choice! As an aside, Netbeans had one supporter, RubyMine and Emacs had zero. The groundswell of support for vim (and the cheering) was impressive!</p>
<p>PS - this is a <em>very</em> nerdy post, but as a long time vim fan, I had to report on it <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/2011/02/08/vim-is-rails-devs-favourite-editor/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Short Talk on rails_refactor at Rails group</title>
		<link>http://jamescrisp.org/2011/02/01/short-talk-on-rails_refactor-at-rails-group/</link>
		<comments>http://jamescrisp.org/2011/02/01/short-talk-on-rails_refactor-at-rails-group/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 11:25:29 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=430</guid>
		<description><![CDATA[I'll be giving a short talk with Ryan Bigg on Rails Refactor at the next Sydney Rails Group (RORO) meet (Tuesday, Feb 8 from 7pm) . We'll be talking about Rails Refactor's birth at a hack night last year, what it can do for you right now, and its bright future as your refactoring tool [...]]]></description>
				<content:encoded><![CDATA[<p>I'll be giving a short talk with <a href="http://twitter.com/ryanbigg">Ryan Bigg</a> on <a href="https://github.com/jcrisp/rails_refactor">Rails Refactor</a> at the next Sydney Rails Group (<a href="http://rubyonrails.com.au/">RORO</a>) meet (Tuesday, Feb 8 from 7pm) . We'll be talking about Rails Refactor's birth at a hack night last year, what it can do for you right now, and its bright future as your refactoring tool of choice. Hope to see you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2011/02/01/short-talk-on-rails_refactor-at-rails-group/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Short Talk: Starting Android Development</title>
		<link>http://jamescrisp.org/2011/01/23/short-talk-starting-android-development/</link>
		<comments>http://jamescrisp.org/2011/01/23/short-talk-starting-android-development/#comments</comments>
		<pubDate>Sun, 23 Jan 2011 11:53:30 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[ALT.NET]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=420</guid>
		<description><![CDATA[I'll be giving a short talk on Starting Android Development on Tuesday at the Sydney ALT.NET group. We'll be covering: the platform app design and abstractions Java and IDEs for Android Dev Emulator Code walk through of a simple application I'm writing Richard Banks (@rbanks54) will also be giving a talk on .NET bdd tools. [...]]]></description>
				<content:encoded><![CDATA[<p>I'll be giving a short talk on Starting Android Development on Tuesday at the Sydney ALT.NET group.</p>
<p>We'll be covering:</p>
<ul>
<li>the platform</li>
<li>app design and abstractions</li>
<li>Java and IDEs for Android Dev</li>
<li>Emulator</li>
<li>Code walk through of a simple application I'm writing</li>
</ul>
<p>Richard Banks (<a href="http://twitter.com/rbanks54">@rbanks54</a>) will also be giving a talk on .NET bdd tools.</p>
<p>More info and RSVP on the <a href="http://sydney.ozalt.net/">ALT.NET blog</a>.</p>
<p>See you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2011/01/23/short-talk-starting-android-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating from Palm OS to Android</title>
		<link>http://jamescrisp.org/2011/01/01/migrating-from-palm-os-to-android/</link>
		<comments>http://jamescrisp.org/2011/01/01/migrating-from-palm-os-to-android/#comments</comments>
		<pubDate>Sat, 01 Jan 2011 03:07:50 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=356</guid>
		<description><![CDATA[Palm and its Demise I've been using Palm organisers and smart phones since the year 2000. I enjoyed developing for them, writing several medical applications, and using them extensively for calendaring, contacts and memos (PIM). The Treo smart phones were visionary at the time, providing integrated phone and PIM functionality, plus push email and basic [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://jamescrisp.org/wordpress/wp-content/uploads/2011/01/phones.jpg"><img src="http://jamescrisp.org/wordpress/wp-content/uploads/2011/01/phones-300x203.jpg" alt="" title="phones" width="300" height="203" class="alignleft size-medium wp-image-394" style="margin-right:1.5em;" /></a></p>
<p><strong>Palm and its Demise</strong><br />
I've been using <a href="http://www.palm.com/au/">Palm</a> organisers and smart phones since the year 2000. I enjoyed developing for them, writing several medical applications, and using them extensively for calendaring, contacts and memos (PIM). The Treo smart phones were visionary at the time, providing integrated phone and PIM functionality, plus push email and basic web browsing. </p>
<p>I was at the lavish developer conference in Sydney, when Palm was the market leader, and announced they were splitting into two separate businesses - software and hardware, and developing a new OS (Cobalt), which never saw the light of day. After that, Palm slowly lost its lead. I would have been interested to try out Palm's last throw - the Pre and WebOS - but it never made it to Australia. Now Palm has been <a href="http://www.hp.com/hpinfo/newsroom/press/2010/100428xa.html">purchased by HP</a>, and it is abundantly clear that Palm has had its day, and it's time to move on. Goodbye Treo 650 and Palm OS Garnet!</p>
<p><strong>Where to next?</strong><br />
Well, major contenders for smart phones at this point are iOS and Android (sorry Windows Phone 7, maybe next release <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). The iPhone is a nicely crafted piece of consumer electronics, and it's the obvious choice for many people. Personally, I like the polish, but find the limitations of the OS and clumsy notification system, vendor lock in and tightly controlled environment does not appeal. Android, especially with 2.2, is pretty smooth. It requires a lot more tweaking than an iPhone to get it to a good state, but once set up, it's a really nice experience and lets you do quite a lot of stuff you can't do on an iPhone. I chose a HTC Desire HD and Android 2.2.</p>
<p><strong>Android Migration</strong><br />
What I particularly want to share is how I migrated my data across from Palm OS to Google services and Android 2.2, and what applications I chose to replace the beautifully crafted Palm PIM system. There's still some Palm users out there hanging on, and I'd encourage you to take the leap and move over to Android. </p>
<p><Strong>Aims</strong></p>
<ul>
<li>Powerful calendar app on the Phone with hour by hour day view, easy and quick to add/change events, and ability to include additional public calendars. Synchronisation with a desktop application.</li>
<li>Contacts synced with Google mail / Google contacts and a desktop application.</li>
<li>Memos/Notes synced <i>only</i> with a desktop application (not cloud)</li>
<li>Push email</li>
</ul>
<p><strong>Apps &#038; Architecture</strong><br />
After quite a bit of research and trial, I decided to go with:</p>
<ul>
<li>Google services for Calendar and Contact storage in the cloud</li>
<li><a href="https://sites.google.com/site/businesscalendarforandroid/">Business Calendar</a> for android calendar app. Uses Google services, day by day view and supports multiple calendars. It works pretty well though still in Beta, and has frequent updates and improvements.</li>
<li>Built in contact app from HTC. It syncs with Google contacts (links to facebook too) and works well with the phone app. It's meant to sync with twitter too but HTC apps for twitter don't seem to have been updated for new Twitter authentication system.</li>
<li>Outlook 2007 for the desktop PIM application (I prefer Palm desktop, but yes, no future there)</li>
<li><a href="http://www.daveswebsite.com/software/gsync/">gSync</a> to synchronise Outlook with Google services for Calendar and Contacts (this works pretty well, though not 100% reliably for things like deleting one occurrence of repeating events). I also set the synchronisation for the calendar to only be 100 days in the past and future as this made it a lot faster to sync)</li>
<li><a href="http://www.jointlogic.com/b-folders/2/">B-Folders</a> Android app and wireless sync to desktop for memos/notes (B-Folders works ok for this but is a bit clunky for editing notes on the phone and requires you to enter a password frequently)</li>
<li>Built in Gmail app works well for email and I use the Gmail web client with offline sync on my PC</li>
</ul>
<p><strong>Data Migration</strong></p>
<ul>
<li>First, sync data with Outlook. Only outlook <= 2003 is supported. I installed Outlook 2000 for the sync. To change from Palm desktop to Outlook for HotSync, on Windows, run PalmOne > PIM Conduit Sync > Sync with Outlook from the start menu. If you don't have this app, you can download the latest version of Palm Desktop from the Palm site and it will include it.</li>
<li>I had a lot of errors during sync but managed through largely retrying to get a clean sync to happen.</li>
<li>After a clean sync, I upgraded my outlook to 2007 as this has a better user interface and works with gSync.</li>
<li>Next, I used gSync to sync about a year of past calendar data and all contacts into Google services. It works pretty well. Some calendar events seemed to get duplicated but not enough to be a major hassle. I did try syncing more years of history in Calendar with the cloud, but it seemed to slow down my Business Calendar start up time significantly, so I cleared out everything and only synced a much smaller length of time - about a year. I then changed the sync to only 100 days in the past and future to make it run faster (takes about 3 minutes). I currently have the sync run a few times a day automatically but sometimes kick it off manually too.</li>
<li>Use 'Google contacts > More actions > Find &#038; Merge Duplicates' to clean up and combine your contacts. I had a lot of email addresses in Google contacts which also had contact records from the Palm. This command did a good job combining them.</li>
<li>I exported all memos using Palm Desktop into individual text files (one per category), and then imported them into B-Folders as per <a href="http://androidforums.com/android-applications/97604-best-palm-desktop-memo-replacement.html">these instructions</a>. I had to manually change line endings (\r\n to \n) to avoid double spacing. A few days later, a new version of B-Folders was released which can import all exported Palm memos from a single categorised file. I haven't tried this but feature, but it sounds like a time saver! The B-folders sync between phone and desktop app is manual and initiated from the phone. It has worked well so far.</li>
</ul>
<p><strong>Conclusion</strong><br />
In conclusion, I now have my data and quite workable PIM functionality on my Android phone. Business Calendar has a great multi-day view that my old palm didn't, but it is a bit slower to add new events. The HTC Contacts app gets pictures from Facebook which is pretty cool, and syncs with my gmail so I don't have to maintain email addresses in two places. It is a bit more clunky to edit and add contacts though. On the memo/note front, B-folders encrypts notes which is cool... but a bit irritating to need to enter your password every time you launch the program. Also it is more clunky to edit notes and does not save your last open note, and position in the note between launches. The rest of the phone functionality is great though and a huge step forward from the Palm. It's really for a separate post to talk about these, but good web browser, GPS with maps, train timetables, movie times near you, twitter client, etc make it an amazing device and well worth the upgrade. </p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2011/01/01/migrating-from-palm-os-to-android/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>TRON and NORT</title>
		<link>http://jamescrisp.org/2010/12/22/tron-and-nort/</link>
		<comments>http://jamescrisp.org/2010/12/22/tron-and-nort/#comments</comments>
		<pubDate>Tue, 21 Dec 2010 23:57:34 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=340</guid>
		<description><![CDATA[On the ultra-geeky front, I watched the original TRON last night, kindly leant to me by my buddy Doctor Dray. Having never seen it before, but heard a lot about it, I was keen to watch it at last. The core idea of computer programs personified is pretty cool, and the 80s rendering is interesting [...]]]></description>
				<content:encoded><![CDATA[<p>On the ultra-geeky front, I watched the original TRON last night, kindly leant to me by my buddy <a href="http://www.doctordray.com/">Doctor Dray</a>. Having never seen it before, but heard a lot about it, I was keen to watch it at last. The core idea of computer programs personified is pretty cool, and the 80s rendering is interesting to watch (looks like stuff we did in computer graphics class at uni!). The plot does stretch belief a bit too thin at times though. To get an idea how far movie tech has come between the 80s and today, check out the <a href="http://www.youtube.com/watch?v=3efV2wqEjEY">original 80s trailer</a> and the <a href="http://www.youtube.com/watch?v=a1IpPpB3iWI">new Tron Legacy trailer</a>.</p>
<p>Also, at high school, I and my fellow geeks spent quite a bit of time writing games in C like the TRON light cycle game, cunningly avoiding copyright violation by calling them NORT. After writing the 2 player version, we moved on to writing simple AIs so that you could play against the computer. Recently going through an old computer's hard disk, I found the code for these. Thanks to the backward comparability features of Windows they still run, although they were written in Borland C/C++ for DOS! Amazing blast from the past.. here's a picture of AI NORT in action:</p>
<p><a href="http://jamescrisp.org/wordpress/wp-content/uploads/2010/12/nort.jpg"><img src="http://jamescrisp.org/wordpress/wp-content/uploads/2010/12/nort-300x179.jpg" alt="" title="NORT" width="300" height="179" class="alignnone size-medium wp-image-344" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/12/22/tron-and-nort/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>nRake Microsoft Case Study</title>
		<link>http://jamescrisp.org/2010/11/27/nrake-microsoft-case-study/</link>
		<comments>http://jamescrisp.org/2010/11/27/nrake-microsoft-case-study/#comments</comments>
		<pubDate>Sat, 27 Nov 2010 02:20:11 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[ALT.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Design / Architecture]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=318</guid>
		<description><![CDATA[nRake is now the subject of a Microsoft case study. Check it out here: Microsoft Case Study on nRake in PDF format UPDATE: Now on the Microsoft Case Study site.]]></description>
				<content:encoded><![CDATA[<p><a href="https://github.com/jcrisp/nRake">nRake</a> is now the subject of a Microsoft case study. Check it out here:</p>
<ul>
<li><a href="http://jamescrisp.org/wordpress/wp-content/uploads/2010/11/MSCaseStudy.pdf">Microsoft Case Study on nRake in PDF format</a></li>
</ul>
<p><b>UPDATE:</b> Now on the <a href="http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=4000008831">Microsoft Case Study site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/11/27/nrake-microsoft-case-study/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rails Refactor &amp; Hack Night</title>
		<link>http://jamescrisp.org/2010/11/27/rails-refactor-hack-night/</link>
		<comments>http://jamescrisp.org/2010/11/27/rails-refactor-hack-night/#comments</comments>
		<pubDate>Sat, 27 Nov 2010 02:00:52 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=302</guid>
		<description><![CDATA[During the RORO hack night last Wednesday, Ryan Bigg (@ryanbigg) and I worked on a Rails Refactor, something I've been meaning to get going for a long time. How often have you wasted time doing renames in rails? Sure it's hard to automate everything without understanding the code, but there sure are a lot of [...]]]></description>
				<content:encoded><![CDATA[<p>During the <a href="http://wiki.rubyonrails.com.au/index.php/Rorosyd_hack_meetup#Hack_Night_.40_ThoughtWorks">RORO hack night</a>  last Wednesday, <a href="http://ryanbigg.com/">Ryan Bigg</a> (<a href="http://twitter.com/ryanbigg/">@ryanbigg</a>) and I worked on a <a href="https://github.com/jcrisp/rails_refactor">Rails Refactor</a>, something I've been meaning to get going for a long time. </p>
<p>How often have you wasted time doing renames in rails? Sure it's hard to automate everything without understanding the code, but there sure are a lot of mechanical steps that you can easily automate. Ryan and I took on controller renames and got a fair way in the few hours we spent on the night.</p>
<p><a href="https://github.com/jcrisp/rails_refactor">Code is on github</a></p>
<p>To rename a controller:<br />
$ <strong>rails_refactor.rb rename OldController NewController</strong></p>
<ul>
<li>renames controller file &#038; class name in file</li>
<li>renames controller spec file &#038; class name in file</li>
<li>renames view directory</li>
<li>renames helper file &#038; module name in file</li>
<li>updates routes</li>
</ul>
<p>To rename a controller action:<br />
$ <strong>rails_refactor.rb rename DummyController.old_action new_action</strong></p>
<ul>
<li>renames controller action in controller class file</li>
<li>renames view files for all formats</li>
</ul>
<p>Looking to extend it with model renames, and then more complex refactoring.<br />
If you like it, please <a href="https://github.com/jcrisp/rails_refactor">fork</a> and contribute <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/2010/11/27/rails-refactor-hack-night/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Odd Date and Time Comparisons in Rails &amp; Hack night</title>
		<link>http://jamescrisp.org/2010/11/24/odd-date-and-time-comparisons-in-rails-hack-night/</link>
		<comments>http://jamescrisp.org/2010/11/24/odd-date-and-time-comparisons-in-rails-hack-night/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 06:08:47 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=244</guid>
		<description><![CDATA[While comparing Dates and Times in Rails (both 2.3 and 3), I came across an odd behaviour: >> Time.parse("Mon, 26 Jul 2010 9:59") == Date.new(2010, 7, 26) => false >> Time.parse("Mon, 26 Jul 2010 10:00") == Date.new(2010, 7, 26) => true >> Time.parse("Mon, 26 Jul 2010 10:01") == Date.new(2010, 7, 26) => false Also >> [...]]]></description>
				<content:encoded><![CDATA[<p>While comparing Dates and Times in Rails (both 2.3 and 3), I came across an odd behaviour: </p>
<p><code>>> Time.parse("Mon, 26 Jul 2010 9:59") == Date.new(2010, 7, 26)<br />
=> false<br />
>> Time.parse("Mon, 26 Jul 2010 10:00") == Date.new(2010, 7, 26)<br />
=> true<br />
>> Time.parse("Mon, 26 Jul 2010 10:01") == Date.new(2010, 7, 26)<br />
=> false</code></p>
<p>Also</p>
<p><code>>> Date.new(2010, 7, 26) == Time.parse("Mon, 26 Jul 2010 10:00")<br />
=> false (Rails 2.3)<br />
=> nil (Rails 3)<br />
>> Date.new(2010, 7, 26) == Time.parse("Mon, 26 Jul 2010 0:00")<br />
=> false (Rails 2.3)<br />
=> nil (Rails 3)<br />
</code></p>
<p>Tonight, we'll be having the <a href="http://wiki.rubyonrails.com.au/index.php/Rorosyd_hack_meetup#Hack_Night_.40_ThoughtWorks">RORO hack night</a> in the ThoughtWorks Sydney office, with a focus on open source projects (your own or contributing). A patch for this date/time behaviour might be an interesting area to pursue.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/11/24/odd-date-and-time-comparisons-in-rails-hack-night/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ruby 1.8 Scoping and Blocks</title>
		<link>http://jamescrisp.org/2010/10/23/ruby-scoping-and-blocks/</link>
		<comments>http://jamescrisp.org/2010/10/23/ruby-scoping-and-blocks/#comments</comments>
		<pubDate>Sat, 23 Oct 2010 00:02: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/?p=278</guid>
		<description><![CDATA[Quick ruby quiz.. after these two lines execute, what is the value of number? >> number = 5 >> (1..10).each {&#124;number&#124; print number} Well, number will be 10, thanks to the block being run and re-assigning the value of number. This can cause you some pretty subtle bugs if you happen to have the same [...]]]></description>
				<content:encoded><![CDATA[<p>Quick ruby quiz.. after these two lines execute, what is the value of number?</p>
<p>>> number = 5<br />
>> (1..10).each {|number| print number}</p>
<p>Well, number will be 10, thanks to the block being run and re-assigning the value of number. This can cause you some pretty subtle bugs if you happen to have the same name for a local/function argument, and as a variable name in a block.</p>
<p>In C#, the compiler is kind enough to tell you that this would be a very bad idea and give you an error.</p>
<p>And thanks to Sudhinda for commenting - this has been fixed in Ruby 1.9. In 1.9, the variable used as the argument in the block does not affect the variable outside the block.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/10/23/ruby-scoping-and-blocks/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Showing Hidden Files in Mac Finder</title>
		<link>http://jamescrisp.org/2010/09/15/showing-hidden-files-in-mac-finder/</link>
		<comments>http://jamescrisp.org/2010/09/15/showing-hidden-files-in-mac-finder/#comments</comments>
		<pubDate>Wed, 15 Sep 2010 04:21:35 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=266</guid>
		<description><![CDATA[If you've been longing for your Mac finder to show all the files on disk, then this command is for you. Run on the console: defaults write com.apple.finder AppleShowAllFiles TRUE killall Finder Now you'll be able to see all the .config files in your home directory and all the normal Unix directories on the root.]]></description>
				<content:encoded><![CDATA[<p>If you've been longing for your Mac finder to show all the files on disk, then this command is for you. Run on the console:</p>
<p><code>defaults write com.apple.finder AppleShowAllFiles TRUE<br />
killall Finder<br />
</code>Now you'll be able to see all the .config files in your home directory and all the normal Unix directories on the root.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/09/15/showing-hidden-files-in-mac-finder/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Azure Build and Deploy using Powershell</title>
		<link>http://jamescrisp.org/2010/08/15/azure-build-and-deploy-using-powershell/</link>
		<comments>http://jamescrisp.org/2010/08/15/azure-build-and-deploy-using-powershell/#comments</comments>
		<pubDate>Sun, 15 Aug 2010 09:30:20 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/?p=248</guid>
		<description><![CDATA[Started working with Windows Azure? Want to have automated build and deploy, rather than clicking around in a web console or Visual Studio? Check out the AzureBuildDeploy repository on GitHub. I set this up for an Azure proof of concept project. It contains Powershell scripts for simple automated packaging, build and deploy, and a dummy [...]]]></description>
				<content:encoded><![CDATA[<p>Started working with Windows Azure? Want to have automated build and deploy, rather than clicking around in a web console or Visual Studio?</p>
<p>Check out the <a href="http://github.com/jcrisp/AzureBuildDeploy">AzureBuildDeploy repository</a> on GitHub.</p>
<p>I set this up for an Azure proof of concept project. It contains Powershell scripts for simple automated packaging, build and deploy, and a dummy WCF application for deployment to the cloud. The WCF application can however be easily replaced with a web application or what ever other .NET application you would like to host in the cloud.</p>
<p><strong>How to use</strong></p>
<ul>
<li>Clone or download the source from <a href="http://github.com/jcrisp/AzureBuildDeploy">http://github.com/jcrisp/AzureBuildDeploy</a></li>
<li>Update the $serviceName at the top of build-package-deploy.ps1</li>
<li>Update the certificate details, and subscription id at the top of deploy.ps1</li>
<li>If you plan to use SqlAzure (as in my proof of concept), update the connection details in HelloWorldService.svc.cs. If you don't plan to use SqlAzure, just stub out the whole FindFirstGreetingUsingSqlAzure() method by returning a string.
<li>Test out deployment to the cloud (run build-package-deploy.ps1). You can ensure it is working using the sample client in the repository. </li>
<li>Now you've got everything working, replace the dummy WCF application with whatever you want.</li>
</ul>
<p><strong>Notes</strong><br />
In my experience, the deployment of a simple application via these scripts, Visual Studio or the console takes about 16 minutes, from start of deploy to the service able to accept clients. This is extremely slow - I hope it improves!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/08/15/azure-build-and-deploy-using-powershell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Workaround for Subversion (SVN) certificate verification error: insecure algorithm on Ubuntu 10.04 Lucid Lynx</title>
		<link>http://jamescrisp.org/2010/06/05/workaround-for-subversion-svn-certificate-verification-error-insecure-algorithm-on-ubuntu-1004-lucid-lynx/</link>
		<comments>http://jamescrisp.org/2010/06/05/workaround-for-subversion-svn-certificate-verification-error-insecure-algorithm-on-ubuntu-1004-lucid-lynx/#comments</comments>
		<pubDate>Sat, 05 Jun 2010 04:19:31 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/06/05/workaround-for-subversion-svn-certificate-verification-error-insecure-algorithm-on-ubuntu-1004-lucid-lynx/</guid>
		<description><![CDATA[If you try to check out your code from a hosted subversion repository, under your shiny new Ubuntu 10.04, you may be disappointed to have it fail with the error: svn: OPTIONS of 'https://server.com/repo': Certificate verification error: signed using insecure algorithm (https://server.com/repo) Despite multiple threads on various linux and subversion forums which didn't really help [...]]]></description>
				<content:encoded><![CDATA[<p>If you try to check out your code from a hosted subversion repository, under your shiny new Ubuntu 10.04, you may be disappointed to have it fail with the error:</p>
<p><code>svn: OPTIONS of 'https://server.com/repo': Certificate verification error: signed using insecure algorithm (https://server.com/repo)</code></p>
<p>Despite multiple threads on <a href="http://www.mail-archive.com/debian-bugs-rc@lists.debian.org/msg192836.html">various</a> <a href="https://bugs.launchpad.net/ubuntu/+source/neon27/+bug/576750">linux</a> and <a href="http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&#038;viewType=browseAll&#038;dsMessageId=2401276">subversion</a> forums which didn't really help (it's not subversion's fault, it's from gnu-utils, and yes, it would be great if everyone could get all their hosting providers to upgrade their certificates, and you could patch and recompile relevant utils), I finally found a work around <a href="http://georgik.sinusgear.com/2009/10/26/subversion-problem-signed-using-insecure-algorithm/">here in Slovak</a>. With a bit of help from Google translate, here is the work around:</p>
<p>Add to the end of your ~/.subversion/servers file:<br />
<code>ssl-trust-default-ca = no </code></p>
<p>It means you'll have to verify every certificate manually, but at least you'll be able to check out your code until you can get your hosting provider to update their certificates! Happy days!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/06/05/workaround-for-subversion-svn-certificate-verification-error-insecure-algorithm-on-ubuntu-1004-lucid-lynx/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>ACS Alm Talk: Presentation Wrap Up &amp; Slides</title>
		<link>http://jamescrisp.org/2010/06/03/acs-alm-talk-presentation-wrap-up-slides/</link>
		<comments>http://jamescrisp.org/2010/06/03/acs-alm-talk-presentation-wrap-up-slides/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 01:52:03 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Design / Architecture]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/06/03/acs-alm-talk-presentation-wrap-up-slides/</guid>
		<description><![CDATA[Thanks everyone who came along last night. It was a fun session, with a lot of lively discussion, especially around project management and software design. As mentioned during the talk, you might want to check out nRake for .NET builds and psDeploy for Powershell deployments. Here are the slides from the talk. If you have [...]]]></description>
				<content:encoded><![CDATA[<p>Thanks everyone who came along last night. It was a fun session, with a lot of lively discussion, especially around project management and software design. As mentioned during the talk, you might want to check out <a href="http://github.com/jcrisp/nRake">nRake for .NET builds</a> and <a href="http://wiki.github.com/rprieto/psDeploy/">psDeploy for Powershell deployments</a>. <a href="http://jamescrisp.org/wordpress/wp-content/uploads/2010/06/alm_acs.pptx">Here are the slides from the talk</a>. If you have any more questions or areas to discuss, please feel free to <a href="http://jamescrisp.org/contact">drop me a line</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/06/03/acs-alm-talk-presentation-wrap-up-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ACS Talk: The Ultimate ALM Environment (circa 2010)</title>
		<link>http://jamescrisp.org/2010/05/31/acs-talk-the-ultimate-alm-environment-circa-2010/</link>
		<comments>http://jamescrisp.org/2010/05/31/acs-talk-the-ultimate-alm-environment-circa-2010/#comments</comments>
		<pubDate>Mon, 31 May 2010 01:22:40 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Design / Architecture]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/05/31/acs-talk-the-ultimate-alm-environment-circa-2010/</guid>
		<description><![CDATA[I'll be giving a presentation at an Australian Computer Society Special Interest Group on Wed 2 June, 6:30pm. More details here. The abstract is: Application Lifecycle Management (ALM) covers the whole software development lifecycle and associated processes including project management, business analysis, testing, build and deploy and development. Based on experiences in the field on [...]]]></description>
				<content:encoded><![CDATA[<p>I'll be giving a presentation at an Australian Computer Society Special Interest Group on Wed 2 June, 6:30pm. More <a href="http://www.acs.org.au/nsw/index.cfm?action=event&#038;area=9001&#038;temID=eventdetails&#038;eveID=30167469003491">details here</a>.</p>
<p>The abstract is:</p>
<p><i>Application Lifecycle Management (ALM) covers the whole software development lifecycle and associated processes including project management, business analysis, testing, build and deploy and development. Based on experiences in the field on projects with ThoughtWorks and consulting with other teams, I will describe what I consider to be the ultimate ALM environment, using an agile approach and techniques. This talk will cover goals, assessment criteria, practices, tools, and physical workspace design.</i></p>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/05/31/acs-talk-the-ultimate-alm-environment-circa-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multi-touch two finger scrolling on Samung N150 with Ubuntu 10.04 (Lucid Lynx)</title>
		<link>http://jamescrisp.org/2010/05/25/multi-touch-two-finger-scrolling-on-samung-n150-with-ubuntu-1004-lucid-lynx/</link>
		<comments>http://jamescrisp.org/2010/05/25/multi-touch-two-finger-scrolling-on-samung-n150-with-ubuntu-1004-lucid-lynx/#comments</comments>
		<pubDate>Tue, 25 May 2010 07:12:27 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/05/25/multi-touch-two-finger-scrolling-on-samung-n150-with-ubuntu-1004-lucid-lynx/</guid>
		<description><![CDATA[After much googling, trial and error, finally, a solution for enabling two finger scrolling on Ubuntu 10.04 on my new Samsung n150 netbook. For some reason, it is not possible to enable it through the Mouse configuration in GNOME - the two finger scrolling option is grayed out (disabled). You may need to fine tune [...]]]></description>
				<content:encoded><![CDATA[<p>After much googling, trial and error, finally, a solution for enabling two finger scrolling on Ubuntu 10.04 on my new Samsung n150 netbook. </p>
<p>For some reason, it is not possible to enable it through the Mouse configuration in GNOME - the two finger scrolling option is grayed out (disabled).</p>
<p>You may need to fine tune the MinW and MinZ values - they are configured to work well for my fingers <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><code>synclient VertTwoFingerScroll=1<br />
synclient HorizTwoFingerScroll=1<br />
synclient EmulateTwoFingerMinW=5<br />
synclient EmulateTwoFingerMinZ=48</code></p>
<p>To make these settings sticky, add the synclient calls into a script that runs when you log in.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/05/25/multi-touch-two-finger-scrolling-on-samung-n150-with-ubuntu-1004-lucid-lynx/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>nRake now on IronRuby</title>
		<link>http://jamescrisp.org/2010/05/25/nrake-now-on-ironruby/</link>
		<comments>http://jamescrisp.org/2010/05/25/nrake-now-on-ironruby/#comments</comments>
		<pubDate>Tue, 25 May 2010 04:46:06 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[ALT.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/05/25/nrake-now-on-ironruby/</guid>
		<description><![CDATA[nRake, the premier project and build template for .NET projects using the Rake build system now has a branch for .NET4 using IronRuby. Projects are also updated to VS2010 format, and Albacore gems are now updated to 0.1.5. Check out the IronRuby .NET 4 branch of nRake. or the check out the IronRuby .NET 2 [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://github.com/jcrisp/nRake">nRake</a>, the premier project and build template for .NET projects using the Rake build system now has a branch for .NET4 using <a href="http://ironruby.net/">IronRuby</a>. Projects are also updated to VS2010 format, and <a href="http://github.com/derickbailey/Albacore">Albacore gems</a> are now updated to 0.1.5.</p>
<p>Check out the <a href="http://github.com/jcrisp/nRake/tree/IronRuby4">IronRuby .NET 4 branch of nRake</a>.</p>
<p>or the check out the <a href="http://github.com/jcrisp/nRake/tree/IronRuby2">IronRuby .NET 2 / 3.5 branch of nRake</a>.</p>
<p>Master branch is still using MRI ruby 1.9. However, plans are to change over to IronRuby for master branch in the future. IronRuby is now performing well enough and sufficiently compatible to support .NET builds. IronRuby has advantages around size (smaller download) and more exciting interop possibilities with .NET code.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/05/25/nrake-now-on-ironruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Podcast from ALM Conference</title>
		<link>http://jamescrisp.org/2010/04/27/podcast-from-alm-conference/</link>
		<comments>http://jamescrisp.org/2010/04/27/podcast-from-alm-conference/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 00:18:33 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[ALT.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Design / Architecture]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/04/27/podcast-from-alm-conference/</guid>
		<description><![CDATA[At the ALM Conference, Richard interviewed me for a podcast on the Ultimate ALM Environment circa 2010 as well as a little on build and deployment automation. Check out the podcast on Talking Shop!]]></description>
				<content:encoded><![CDATA[<p>At the ALM Conference, <a href="http://richardsbraindump.blogspot.com/">Richard</a> interviewed me for a podcast on the <a href="http://jamescrisp.org/2010/04/14/australian-alm-conference-and-slides-from-the-ultimate-alm-environment-circa-2010/">Ultimate ALM Environment circa 2010</a> as well as a little on build and deployment automation. <a href="http://www.talkingshopdownunder.com/2010/04/episode-10-james-crisp-live-at-alm.html">Check out the podcast on Talking Shop!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/04/27/podcast-from-alm-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Australian ALM Conference, and slides from ‘The Ultimate ALM Environment circa 2010′</title>
		<link>http://jamescrisp.org/2010/04/14/australian-alm-conference-and-slides-from-the-ultimate-alm-environment-circa-2010/</link>
		<comments>http://jamescrisp.org/2010/04/14/australian-alm-conference-and-slides-from-the-ultimate-alm-environment-circa-2010/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 11:50:58 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Design / Architecture]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/04/14/australian-alm-conference-and-slides-from-the-ultimate-alm-environment-circa-2010/</guid>
		<description><![CDATA[The inaugural Australian ALM Conference has been an interesting 2 days. The first day had a number of insightful talks, especially interesting to hear Sam Guckenheimer on how Microsoft has been reshaping their internal development practices into a more agile model. Today, I enjoyed Richard's agile adoption talk (hear hear!) and the other highlight was [...]]]></description>
				<content:encoded><![CDATA[<p>The inaugural <a href="http://www.australianalm.com.au/">Australian ALM Conference</a> has been an interesting 2 days. The first day had a number of insightful talks, especially interesting to hear <a href="http://blogs.msdn.com/sam/">Sam Guckenheimer</a> on how Microsoft has been reshaping their internal development practices into a more agile model. Today, I enjoyed <a href="http://richardsbraindump.blogspot.com/">Richard</a>'s agile adoption talk (hear hear!) and the other highlight was the last presentation of the day, explaining what's gone into the design of the new Windows 7 Mobile OS (though some things still seem under wraps). Also a pleasure to catch up with some old friends at the conference. </p>
<p>Conference organisation was very good (thanks to <a href="http://myalmblog.com/ ">Anthony Borton</a> and his team). The focus was very Microsoft centric, but next year, the plans are for a much wider variety of content. Lunar Park was a cosy conference venue and fun to go outside during the breaks and see kids screaming on rides and the sun shining on the bridge and harbour.</p>
<p>My presentation was 8.30am this morning (aargh!) but despite the early hour, there was a reasonable turn out and quite a few interested people asking questions. The plan was to co-present with <a href="http://jchyip.blogspot.com/">Jason Yip</a>, but he was called away to Perth so I presented solo. Unlike most other presentations at the conference, Visual Studio and TFS were barely mentioned. Instead I focused on current problems in each area of  ALM, coming up with a criteria to assess this area, and what we usually do on projects to meet this criteria - eg, story walls, story maps, automated build and deploy etc. You can find the <a href="http://jamescrisp.org/wordpress/wp-content/uploads/2010/04/alm.pptx">Powerpoint slides here</a>. The slides are promises for a conversation (ie, mainly images with some notes), so don't hesitate to <a href="http://jamescrisp.org/contact">contact me</a> if you want to chat.</p>
<p>Also, thanks Richard for this photo from the presentation:</p>
<p><a href='http://jamescrisp.org/wordpress/wp-content/uploads/2010/04/mepresenting.jpg' title='James Crisp presenting ‘The Ultimate ALM Environment circa 2010′'><img src='http://jamescrisp.org/wordpress/wp-content/uploads/2010/04/mepresenting.jpg' alt='James Crisp presenting ‘The Ultimate ALM Environment circa 2010′' /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/04/14/australian-alm-conference-and-slides-from-the-ultimate-alm-environment-circa-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Talk: The ultimate (circa 2010) ALM environment</title>
		<link>http://jamescrisp.org/2010/03/20/talk-the-ultimate-circa-2010-alm-environment/</link>
		<comments>http://jamescrisp.org/2010/03/20/talk-the-ultimate-circa-2010-alm-environment/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 13:48:27 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Design / Architecture]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/03/20/talk-the-ultimate-circa-2010-alm-environment/</guid>
		<description><![CDATA[Jason Yip and I will be presenting on "The ultimate (circa 2010) ALM environment" at the Australian ALM Conference on 14 April. We'll be talking about using agile methods and tools for ALM, rather than a vendor suite. Here's the blurb: Based on our experiences in the field on projects and consulting with other teams, [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://jchyip.blogspot.com/">Jason Yip</a> and I will be presenting on "The ultimate (circa 2010) ALM environment" at the <a href="http://www.australianalm.com.au/">Australian ALM Conference</a> on 14 April. We'll be talking about using agile methods and tools for ALM, rather than a vendor suite.</p>
<p>Here's the blurb:</p>
<p><i>Based on our experiences in the field on projects and consulting with other teams, we will describe what we consider to be the ultimate development environment (which is not just about vendor tools). This session will discuss principles, practices, tools, and physical workspace design.</i></p>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/03/20/talk-the-ultimate-circa-2010-alm-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>nRake – Rake builds for .NET</title>
		<link>http://jamescrisp.org/2010/03/20/nrake-rake-builds-for-net/</link>
		<comments>http://jamescrisp.org/2010/03/20/nrake-rake-builds-for-net/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 13:16:01 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Design / Architecture]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/03/20/nrake-rake-builds-for-net/</guid>
		<description><![CDATA[Fed up with XML based builds that are hard to maintain, refactor and extend? Rather than trying to fix this with more xml and community tasks, or re-invent the wheel, let's use Rake. Rake is a mature build system developed by the ruby community which can be applied equally well in the .NET world. To [...]]]></description>
				<content:encoded><![CDATA[<p>Fed up with XML based builds that are hard to maintain, refactor and extend? Rather than trying to fix this with more xml and community tasks, or re-invent the wheel, let's use Rake. Rake is a mature build system developed by the ruby community which can be applied equally well in the .NET world. </p>
<p>To help you get started quickly, I've put together <a href="http://wiki.github.com/jcrisp/nRake/">nRake</a>. nRake provides a template C# .NET solution with a nice directory structure (src, tools, lib, etc), a Rake build, NUnit tests, templated app and web configs for different environments (eg, dev, uat, prod, etc) and Continuous Integration server sample config files. It comes with everything you need - no additional libraries or downloads required, and all the plumbing work has been done for you.  </p>
<p><b>How to use</b></p>
<ul>
<li><a href="http://github.com/jcrisp/nRake">Git clone</a> or <a href="http://github.com/jcrisp/nRake/archives/master">Download nRake as a Zip</a></li>
<li>Rename PlaceHolder app and tests to reflect your project</li>
<li>Run rake in the root of the project. This will clean, compile, template config files and run unit tests.</li>
<li>Start developing your app! How easy was that <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
<p><b>Note:</b> nRake currently uses Ruby 1.9 since IronRuby start up time was prohibitively slow. Hopefully IronRuby will get faster, and then nRake can make use of it. Also nRake uses the <a href="http://albacorebuild.net/">Albacore Gem</a> for .NET build tasks. <a href="http://wiki.github.com/derickbailey/Albacore/">Documentation on Albacore tasks here</a>.</p>
<p><b>Also check out the <a href="http://jamescrisp.org/2010/05/25/nrake-now-on-ironruby/">IronRuby update</a>!</b></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/03/20/nrake-rake-builds-for-net/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Buying Books Online in Australia – Alternatives to Amazon</title>
		<link>http://jamescrisp.org/2010/02/20/buying-books-online-in-australia-alternatives-to-amazon/</link>
		<comments>http://jamescrisp.org/2010/02/20/buying-books-online-in-australia-alternatives-to-amazon/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 06:38:54 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/02/20/buying-books-online-in-australia-alternatives-to-amazon/</guid>
		<description><![CDATA[In the past, I have been a happy customer of Amazon USA for technical books, and more recently, even for fiction. Australian bookshops seem to have very limited and expensive stock, so buying online is an attractive option. Recently some of my colleagues recommended two other options: Book Depository UK: good prices, free international shipping, [...]]]></description>
				<content:encoded><![CDATA[<p>In the past, I have been a happy customer of Amazon USA for technical books, and more recently, even for fiction. Australian bookshops seem to have very limited and expensive stock, so buying online is an attractive option.</p>
<p>Recently some of my colleagues recommended two other options:</p>
<ul>
<li><a href="http://www.bookdepository.co.uk/">Book Depository UK</a>: good prices, free international shipping, fast delivery, but at first glance less books than Amazon</li>
<li><a href="http://www.booko.com.au/">Booko book price comparison</a>: compares multiple sites including Amazon and BookDepository. Presumably make money using affiliate links from search.</li>
</ul>
<p>I'll be giving these a go and posting on the experience in future.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/02/20/buying-books-online-in-australia-alternatives-to-amazon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Monitoring MySQL Slave Replication Status with Ruby and Cron</title>
		<link>http://jamescrisp.org/2010/02/20/monitoring-mysql-slave-replication-status-with-ruby-and-cron/</link>
		<comments>http://jamescrisp.org/2010/02/20/monitoring-mysql-slave-replication-status-with-ruby-and-cron/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 06:08:39 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jamescrisp.org/2010/02/20/monitoring-mysql-slave-replication-status-with-ruby-and-cron/</guid>
		<description><![CDATA[When offering higher levels of uptime on a web site backed by MySQL, a good approach is to set up a MySQL master-slave configuration for failover between servers. This generally works quite well, but once in a while, there is a problem or error that causes the replication to cease. The slave then ceases to [...]]]></description>
				<content:encoded><![CDATA[<p>When offering higher levels of uptime on a web site backed by MySQL, a good approach is to set up a MySQL master-slave configuration for failover between servers. This generally works quite well, but once in a while, there is a problem or error that causes the replication to cease. The slave then ceases to process updates and gets out of sync with the master. </p>
<p>The script below is a quick and easy approach to monitoring the status of replication on the slave. If the slave thread or IO ceases, the slave gets more than 120 seconds behind the master, or there is an error, the script will email all the slave status information to an email address you specify to alert you that you need to log in and sort things out. I run the script from cron so that I get notified fairly soon if a problem arises.</p>
<pre>RAILS_ENV = 'production'
ALERT_EMAIL_ADDRESS = 'me@mydomain.com'

require 'open3'
require 'socket'
require "#{File.dirname(__FILE__)}/../../config/environment.rb"

r = ActiveRecord::Base.connection.execute("show slave status").fetch_hash
unless  r["Slave_IO_Running"] == "Yes" &#038;& r["Slave_SQL_Running"] == "Yes" &#038;&
  r["Last_Errno"] == "0" &#038;& r["Seconds_Behind_Master"].to_i < 120

    status = "*** STATUS ***\\n" + r.to_a.collect { |i| "#{i[0]}: #{i[1]}\\n" }.join
    subject = "MySQL Slave Replication Down on #{Socket.gethostname}"

    Open3.popen3("mail -s \"#{subject}\" #{ALERT_EMAIL_ADDRESS}") do |stdin, stdout, stderr|
       stdin.write(status)
    end
end</pre>
<p><b>Note:</b> This script relies on being part of a rails app to get a database connection. It would be fairly easy to modify it to include db credentials and open the connection.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2010/02/20/monitoring-mysql-slave-replication-status-with-ruby-and-cron/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>.</p>
]]></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>
		<slash:comments>1</slash:comments>
		</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[Book Reviews]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>1</slash:comments>
		</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 [...]]]></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>
		<slash:comments>6</slash:comments>
		</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 [...]]]></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>
		<slash:comments>9</slash:comments>
		</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 book, [...]]]></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>
		<slash:comments>2</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>0</slash:comments>
		</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[Technical]]></category>
		<category><![CDATA[Windows]]></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>
		<slash:comments>2</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>2</slash:comments>
		</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[Book Reviews]]></category>
		<category><![CDATA[Ruby / Rails]]></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 [...]]]></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>
		<slash:comments>1</slash:comments>
		</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>
		<slash:comments>0</slash:comments>
		</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[Book Reviews]]></category>
		<category><![CDATA[Personal]]></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>
		<slash:comments>7</slash:comments>
		</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>
		<slash:comments>2</slash:comments>
		</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[Book Reviews]]></category>
		<category><![CDATA[Ruby / Rails]]></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>
		<slash:comments>0</slash:comments>
		</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[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Windows]]></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>
		<slash:comments>8</slash:comments>
		</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>
<p><strong>UPDATE</strong><br />
These files are now available from my <a href="https://github.com/jcrisp/dotfiles">github dotfiles repository</a>, including the gem inside of the vim/gems_required directory.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2009/02/21/vim-with-find-file-for-rails-like-textmate/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</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[Technical]]></category>
		<category><![CDATA[ThoughtWorks]]></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>
		<slash:comments>2</slash:comments>
		</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[Book Reviews]]></category>
		<category><![CDATA[REST]]></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>
		<slash:comments>1</slash:comments>
		</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[Book Reviews]]></category>
		<category><![CDATA[JavaScript]]></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>
		<slash:comments>3</slash:comments>
		</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>
		<slash:comments>0</slash:comments>
		</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[Design / Architecture]]></category>
		<category><![CDATA[EDI]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[ThoughtWorks]]></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>
		<slash:comments>2</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>2</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[ThoughtWorks]]></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>
		<slash:comments>3</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[ThoughtWorks]]></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 [...]]]></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>
		<slash:comments>3</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>0</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>1</slash:comments>
		</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>
		<slash:comments>6</slash:comments>
		</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 [...]]]></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>
		<slash:comments>3</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[REST]]></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 [...]]]></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>
<p><b>UPDATE:</b>  <a href="http://github.com/jcrisp/simple_rest_client_c_sharp">Source now available on GitHub!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamescrisp.org/2008/08/08/simple-rest-client/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</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>
		<slash:comments>4</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Talks]]></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 [...]]]></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>
		<slash:comments>5</slash:comments>
		</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>
		<slash:comments>6</slash:comments>
		</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>
		<slash:comments>1</slash:comments>
		</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(); } } void VerySlowOperation() { ... etc ... } This was kind of cute - you could make sure that, even if an [...]]]></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>
		<slash:comments>2</slash:comments>
		</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>
		<slash:comments>10</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[WPF]]></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>
		<slash:comments>11</slash:comments>
		</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 [...]]]></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>
		<slash:comments>2</slash:comments>
		</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[Personal]]></category>
		<category><![CDATA[Ruby / Rails]]></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 [...]]]></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>
		<slash:comments>0</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Testing]]></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 [...]]]></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>
		<slash:comments>1</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Testing]]></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>
		<slash:comments>0</slash:comments>
		</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] [...]]]></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>
		<slash:comments>2</slash:comments>
		</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[Book Reviews]]></category>
		<category><![CDATA[Soft Skills and Mind Hacks]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[ThoughtWorks]]></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>
		<slash:comments>1</slash:comments>
		</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[JRuby]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>0</slash:comments>
		</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[Java]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>1</slash:comments>
		</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[Java]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[ThoughtWorks]]></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 [...]]]></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>
		<slash:comments>1</slash:comments>
		</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[Book Reviews]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby / Rails]]></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>
		<slash:comments>0</slash:comments>
		</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>
		<slash:comments>1</slash:comments>
		</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 <img src='http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ?</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>
		<slash:comments>5</slash:comments>
		</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>
		<slash:comments>3</slash:comments>
		</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>
		<slash:comments>3</slash:comments>
		</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[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[YourWeddingPresents.com]]></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>
		<slash:comments>3</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>2</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Talks]]></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 [...]]]></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>
		<slash:comments>1</slash:comments>
		</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>
		<slash:comments>0</slash:comments>
		</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[Personal]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>2</slash:comments>
		</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[Java]]></category>
		<category><![CDATA[JRuby]]></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>
		<slash:comments>1</slash:comments>
		</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[Personal]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[YourWeddingPresents.com]]></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>
		<slash:comments>0</slash:comments>
		</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[Personal]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[YourWeddingPresents.com]]></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>
		<slash:comments>8</slash:comments>
		</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[Java]]></category>
		<category><![CDATA[JRuby]]></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>
		<slash:comments>3</slash:comments>
		</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 [...]]]></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>
		<slash:comments>3</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></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 [...]]]></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>
		<slash:comments>0</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></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>
		<slash:comments>3</slash:comments>
		</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 [...]]]></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>
		<slash:comments>0</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Talks]]></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 [...]]]></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>
		<slash:comments>5</slash:comments>
		</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>
		<slash:comments>6</slash:comments>
		</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>
		<slash:comments>0</slash:comments>
		</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 [...]]]></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>
		<slash:comments>1</slash:comments>
		</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>
		<slash:comments>2</slash:comments>
		</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[C#]]></category>
		<category><![CDATA[Java]]></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 [...]]]></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>
		<slash:comments>8</slash:comments>
		</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>
		<slash:comments>0</slash:comments>
		</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>
		<slash:comments>3</slash:comments>
		</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 [...]]]></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>
		<slash:comments>5</slash:comments>
		</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. [...]]]></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>
		<slash:comments>4</slash:comments>
		</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>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
