<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>I ticked the wrong box &#187; software</title>
	<atom:link href="http://hamishrickerby.com/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://hamishrickerby.com</link>
	<description>Computer says...</description>
	<lastBuildDate>Fri, 23 Jul 2010 07:46:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>iPhone &amp; iPad (iOS) Localizations and Regions</title>
		<link>http://hamishrickerby.com/2010/07/23/iphone-ipad-localizations-regions/</link>
		<comments>http://hamishrickerby.com/2010/07/23/iphone-ipad-localizations-regions/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 07:45:12 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[apple]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile development]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/?p=454</guid>
		<description><![CDATA[Recently I have been doing some localizations of an iOS app from English (US) to English (UK). The iPhone development guides from Apple describe how to support multiple languages (such as English, German, Japanese), but fail to describe how to support multiple variants of a single language. By this I mean support support for US [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I have been doing some localizations of an iOS app from English (US) to English (UK). The iPhone development guides from Apple describe how to support multiple languages (such as English, German, Japanese), but fail to describe how to support multiple variants of a single language. By this I mean support support for US English, English, NZ English, AU English. The word I needed to regionalize was Behavior (or Behaviour, depending where you come from). </p>
<p>In the Apple Developer Library, it explicitly states that for MacOS applications take both the Language and Regional preferences of the user into account, but only look at the preferred <em>language</em> on iOS &#8211; <a href="http://developer.apple.com/iphone/library/documentation/MacOSX/Conceptual/BPInternational/Articles/InternatSupport.html">Support for Internationalization</a>.  This means that a single variant <em>per language</em> is supported. </p>
<p>However, these is a way around this. I&#8217;m not sure if this is a <em>good</em> thing to do, but it works for me and I haven&#8217;t noticed any ill side effects yet.</p>
<p>To support both US English and British English in your iOS application, create 2x Localization.strings files just as you would for multiple language. Put the US English translation file Localization.strings in a directory in your iPhone app called English.lproj (Apple defaults) and the British English translation in a directory named en_GB.lproj (just in case they decide to support regions in the future).</p>
<p>Then, you&#8217;ll need to create some code to manually set the preferred localization.  In your main.m file (yup, main.m is being edited) alter it so it performs some logic similar to below.</p>
<pre class="brush: objc;">
int main(int argc, char *argv[]) {
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
	NSString *locale = [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode];
	if ([language isEqualToString:@&quot;en&quot;] &amp;&amp; [locale isEqualToString:@&quot;GB&quot;]) {
		[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@&quot;en_GB&quot;, @&quot;en&quot;, nil] forKey:@&quot;AppleLanguages&quot;];
	}
	int retVal = UIApplicationMain(argc, argv, nil, nil);
	[pool release];
	return retVal;
}
</pre>
<p>When the line </p>
<pre class="brush: objc;">
int retVal = UIApplicationMain(argc, argv, nil, nil);
</pre>
<p>gets executed, it seems to set up all the Localization bundles before calling the application:didFinishLaunchingWithOptions method on your app delegate, so putting Localization code in the app delegate is too late. So, what the code above does is retrieve the users current language and region, and compares those against pre-determined values &#8211; en for the language and gb for the region. If these match, then I force a new setting in the NSUserDefaults to overwrite the users preferred language. Then, when the UIApplicationManager function gets called, it appears to retrieve the users preferred language setting, and look up the Localization for that &#8211; which in my case I&#8217;ve forced to be en_GB.</p>
<p>One thing you need to be careful about is persistence of this NSUserDefault setting.  It is saved once it&#8217;s set, and persists through multiple application executions. To get around this (lets say the user changes their region back to US), you need to remove the setting after the bundle initialization has taken place.  In you app delegates application:didFinishLaunchingWithOptions method, just execute the following code.</p>
<pre class="brush: objc;">
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@&quot;AppleLanguages&quot;];
</pre>
<p>This wipes out the NSUserDefault setting that the app made in the main.m file.</p>
<p>If anyone knows of issues with this approach (apart from being a dirty hack), or faults with my code please let me know in the comments below. I wish Apple supported different regions per language natively in iOS but they don&#8217;t. This is the only way I&#8217;ve found to do this, and continue to use localization functions such as NSLocalizedString.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-2696058307997556";
/* 468x60, created 29/07/09 */
google_ad_slot = "3174546356";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2010/07/23/iphone-ipad-localizations-regions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving Van</title>
		<link>http://hamishrickerby.com/2010/03/04/moving-van/</link>
		<comments>http://hamishrickerby.com/2010/03/04/moving-van/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 07:35:59 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[apple]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile development]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/?p=445</guid>
		<description><![CDATA[Yesterday when I came home Moving Van&#8217;s sales were up. I was a bit surprised as I hadn&#8217;t done any specific marketing for the app, and what was really odd is that they were only up for the UK. A little investigation and I discover that Moving Van has been featured as &#8220;New and Noteworthy&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday when I came home <a href="http://is.gd/93SaG">Moving Van&#8217;s</a> sales were up. I was a bit surprised as I hadn&#8217;t done any specific marketing for the app, and what was really odd is that they were only up for the UK.  A little investigation and I discover that <a href="http://is.gd/93SaG">Moving Van</a> has been featured as &#8220;New and Noteworthy&#8221; in the iTunes Store UK.</p>
<p><a href="http://hamishrickerby.com/wp-content/uploads/2010/03/Screen-shot-2010-03-03-at-17.52.49.png" rel="lightbox[445]"><img src="http://hamishrickerby.com/wp-content/uploads/2010/03/Screen-shot-2010-03-03-at-17.52.49-300x142.png" alt="Moving Van in the iTunes Store" title="Moving Van as New and Noteworthy" width="300" height="142" class="aligncenter size-medium wp-image-444" /></a></p>
<p>How frickin&#8217; exciting!</p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2010/03/04/moving-van/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculate age in objective-c</title>
		<link>http://hamishrickerby.com/2010/01/07/calculate-age-in-objective-c/</link>
		<comments>http://hamishrickerby.com/2010/01/07/calculate-age-in-objective-c/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 19:30:13 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[apple]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile development]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/?p=432</guid>
		<description><![CDATA[For an iPhone application I&#8217;m developing for a client I need to capture the birthdate of a user, and then show their age on a profile screen. I went looking for a function to help with this simple and tedious task, but couldn&#8217;t find any example code that could be lifted to help me, so [...]]]></description>
			<content:encoded><![CDATA[<p>For an iPhone application I&#8217;m developing for a client I need to capture the birthdate of a user, and then show their age on a profile screen. I went looking for a function to help with this simple and tedious task, but couldn&#8217;t find any example code that could be lifted to help me, so I rolled my own.  Here is what I made, steal as you see fit.</p>
<pre class="brush: objc;">
- (NSInteger)age:(NSDate *)dateOfBirth {
  NSCalendar *calendar = [NSCalendar currentCalendar];
  unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
  NSDateComponents *dateComponentsNow = [calendar components:unitFlags fromDate:[NSDate date]];
  NSDateComponents *dateComponentsBirth = [calendar components:unitFlags fromDate:dateOfBirth];

  if (([dateComponentsNow month] &lt; [dateComponentsBirth month]) ||
      (([dateComponentsNow month] == [dateComponentsBirth month]) &amp;&amp; ([dateComponentsNow day] &lt; [dateComponentsBirth day]))) {
    return [dateComponentsNow year] - [dateComponentsBirth year] - 1;
  } else {
    return [dateComponentsNow year] - [dateComponentsBirth year];
  }
}
</pre>
<p><script type="text/javascript"><!--
google_ad_client = "pub-2696058307997556";
/* 468x60, created 29/07/09 */
google_ad_slot = "3174546356";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2010/01/07/calculate-age-in-objective-c/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Passenger (Ruby on Rails) + PHP on OSX</title>
		<link>http://hamishrickerby.com/2009/08/15/passenger-ruby-on-rails-php-on-osx/</link>
		<comments>http://hamishrickerby.com/2009/08/15/passenger-ruby-on-rails-php-on-osx/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 10:06:53 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[apple]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/?p=391</guid>
		<description><![CDATA[I&#8217;ve spent the last hour or so trying various things out to get passenger and PHP to play nicely together on my mac under OS X (Leopard) and apache2. The situation I was finding was that PHP apps would run, but only if you explicitly call the script (ie index.php) rather than just the directory. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent the last hour or so trying various things out to get passenger and PHP to play nicely together on my mac under OS X (Leopard) and apache2.</p>
<p>The situation I was finding was that PHP apps would run, but only if you explicitly call the script (ie <tt>index.php</tt>) rather than just the directory.  If you called the directory, passenger would take over and give me a rails routing error.</p>
<p>The issue was to do with the passenger vhosts configuration.  On my machine I have an number of ruby on rails apps configured with the passenger preferences pane (creating vhost entries within <tt>/private/etc/apache2/passenger_pane_vhosts/</tt>.  I have enabled user_dirs, so that the users of my machine&#8217;s pages (and other apps) are served from their <tt>~username/Sites</tt> directory.</p>
<p>My users configuration info for apache is installed in <tt>/private/etc/apache2/users/</tt>, and the instructions to load the configuration from that directory is stored within <tt>/private/etc/apache2/extra/httpd-userdir.conf</tt> (content below).</p>
<pre class="brush: bash;">
# Settings for user home directories
#
# Required module: mod_userdir
#
# UserDir: The name of the directory that is appended onto a user's home
# directory if a ~user request is received.  Note that you must also set
# the default access control for these directories, as in the example below.
#
UserDir Sites
#
# Users might not be in /Users/*/Sites, so use user-specific config files.
#
Include /private/etc/apache2/users/*.conf
</pre>
<p>To get everything working together nicely, I merely wrapped this inside a vhosts configuration directive, and gave it a ServerName of localhost &#8211; so that this vhost would be the one that responds to requests for localhost, rather than some random passenger vhost assuming it was the boss of everything.  New <tt>/private/etc/apache2/extra/httpd-userdir.conf</tt> below.</p>
<pre class="brush: bash;">
&lt;VirtualHost *:80&gt;
  ServerName localhost
  UserDir Sites
  Include /private/etc/apache2/users/*.conf
&lt;/VirtualHost&gt;
</pre>
<p>Thanks to this, all of my rails apps are served under passenger, and I can have static HTML, PHP and camping apps (previously configured &#8211; nothing to do with the above) all served from within my <tt>~username/Sites</tt> directory.</p>
<p>Hope this helps someone.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-2696058307997556";
/* 468x60, created 29/07/09 */
google_ad_slot = "3174546356";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2009/08/15/passenger-ruby-on-rails-php-on-osx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Feedzirra</title>
		<link>http://hamishrickerby.com/2009/03/20/feedzirra/</link>
		<comments>http://hamishrickerby.com/2009/03/20/feedzirra/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 07:51:46 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/?p=313</guid>
		<description><![CDATA[Feedzirra is an RSS feed fetching and parsing library that I quite like. For a project I&#8217;m working on with a mate we need to be able to parse and receive updates from (potentially) a large number of RSS feeds. Feedzirra seemed the ticket, but didn&#8217;t have support for itunes style RSS feeds &#8211; so [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/pauldix/feedzirra/tree/master">Feedzirra</a> is an RSS feed fetching and parsing library that I quite like.  For a project I&#8217;m working on with a mate we need to be able to parse and receive updates from (potentially) a large number of RSS feeds.  Feedzirra seemed the ticket, but didn&#8217;t have support for itunes style RSS feeds &#8211; so I added it.  </p>
<p>This was basically my first (well, second, but that wasn&#8217;t public) go with github, and first contribution to an open source project.  <a href="http://www.pauldix.net/2009/03/feedzirra-release-adds-simple-custom-parsing-and-more.html">Paul Dix accepted my code</a>, and I&#8217;m oddly excited about it all.</p>
<p>AND to make things even better, someone has already started to enhance my contribution.  Woo hoo!</p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2009/03/20/feedzirra/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>User Preferences on iPhone</title>
		<link>http://hamishrickerby.com/2009/01/04/user-preferences-on-iphone/</link>
		<comments>http://hamishrickerby.com/2009/01/04/user-preferences-on-iphone/#comments</comments>
		<pubDate>Sun, 04 Jan 2009 11:23:42 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[apple]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile development]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/?p=276</guid>
		<description><![CDATA[Getting and setting user preferences on iPhone is pretty darn easy. Â I was looking for a way to automagically store a users email address between different application sessions, and found the linked tutorial immensely helpful (iphonedevelopertips.com). I needed to store a string (NSString object actually) however, and the tutorial didn&#8217;t help me with that. The [...]]]></description>
			<content:encoded><![CDATA[<p>Getting and setting user preferences on iPhone is pretty darn easy. Â I was looking for a way to automagically store a users email address between different application sessions, and found the linked tutorial immensely helpful (<a href="http://iphonedevelopertips.com/cocoa/read-and-write-user-preferences.html" target="_blank">iphonedevelopertips.com</a>).</p>
<p>I needed to store a string (NSString object actually) however, and the tutorial didn&#8217;t help me with that. The NSUserDefaults object has dedicated methods for storing and retrieving BOOL, float, and NSInteger values.  It also has a setObject:forKey: method &#8211; which is what I ended up using.  The setObject method handles data of types NSData, NSString, NSDate, NSArray or NSDictitionary &#8211; making it incredibly useful indeed.</p>
<p>My Preferences.h</p>
<pre class="brush: cpp;">
#import &lt;Foundation/Foundation.h&gt;
#import &quot;Constants.h&quot;
@interface Preferences : NSObject {
}
+ (NSString *)emailAddress;
+ (BOOL)setPreferences:(NSString *)emailAddress;
@end
</pre>
<p>My Preferences.m</p>
<pre class="brush: cpp;">
#import &quot;Preferences.h&quot;

@implementation Preferences

/*-------------------------------------------
* Return the users default email address
*-------------------------------------------*/
+ (NSString *)emailAddress {
  NSString *returnValue;
  // If preference exists
  if ([[NSUserDefaults standardUserDefaults] stringForKey:kPreferencesEmailAddress]) {
    returnValue = [[NSUserDefaults standardUserDefaults] stringForKey:kPreferencesEmailAddress];
  } else {
    returnValue = @&quot;&quot;;
  }
  return returnValue;
}

/*-------------------------------------------
* Write preferences to system
*-------------------------------------------*/
+ (BOOL)setPreferences:(NSString *)emailAddress {
  // Set values
  [[NSUserDefaults standardUserDefaults] setObject:emailAddress forKey:kPreferencesEmailAddress];
  // Return the results of attempting to write the preferences to system
  return [[NSUserDefaults standardUserDefaults] synchronize];
}
@end
</pre>
<p>kPreferencesEmailAddress is a constant I&#8217;ve defined with the key value of the users email address.  It just makes sure I don&#8217;t mistype anything.</p>
<p>Key (only) differences between my code and the code at <a href="http://iphonedevelopertips.com/cocoa/read-and-write-user-preferences.html" target="_blank">iphonedevelopertips.com</a> are the use of the objectForKey method to set the NSString value, and stringForKey to retrieve the object and cast it to a NSString object.</p>
<p>Hope that helps someone!</p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2009/01/04/user-preferences-on-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Radiant CMS Tutorial &#8211; Custom Javascript in Admin Pages</title>
		<link>http://hamishrickerby.com/2008/08/15/radiant-cms-tutorial-custom-javascript-in-admin-pages/</link>
		<comments>http://hamishrickerby.com/2008/08/15/radiant-cms-tutorial-custom-javascript-in-admin-pages/#comments</comments>
		<pubDate>Fri, 15 Aug 2008 19:00:45 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/?p=245</guid>
		<description><![CDATA[At the moment I&#8217;m working on a fairly complex extension for Radiant CMS. In creating the administrative pages I want to use a javascript library that is not distributed with the core radiant code. This post will describe how to implement your own extension that can use an external javascript library, without playing around with any [...]]]></description>
			<content:encoded><![CDATA[<p>At the moment I&#8217;m working on a fairly complex extension for <a href="http://radiantcms.org/" target="_blank">Radiant CMS</a>. In creating the administrative pages I want to use a javascript library that is not distributed with the core radiant code. This post will describe how to implement your own extension that can use an external javascript library, without playing around with any of the core radiant files to inject the javascript into the administrative layout.</p>
<p>It&#8217;s actually really easy to do.  If you haven&#8217;t created a Radiant extension before I&#8217;d recommend following <a href="http://wiki.radiantcms.org/Creating_Radiant_Extensions" target="_blank">this tutorial</a> on the <a href="http://wiki.radiantcms.org" target="_blank">Radiant wiki</a>.</p>
<p>Inside the Radiant GEM, the standard page layout resides at app/views/layouts/application.html.haml</p>
<p>The lines of code that insert the javascript tags are:</p>
<pre class="brush: ruby;">
- @javascripts.uniq.each do |javascript|
  = javascript_include_tag javascript
</pre>
<p>The @javascripts variable is populated from inside the app/controllers/application_controller.rb file. The culprit is below.</p>
<pre class="brush: ruby;">
def include_javascript(script)
  @javascripts &lt;&lt; script
end
</pre>
<p>Pretty simple huh? So, all you need to do, is call this method from within your new controller, because all controllers inherit from the application_controller.rb file, so they have access to this method, and you can have different javascript included for each method if you so wish. In (assuming the example LinkRoll extension was built as linked above) vendor/extensions/link_roll/app/controllers/admin/links_controller.rb</p>
<pre class="brush: ruby;">
def index
  include_javascript(&quot;admin/mootools-1.2-core-yc.js&quot;)
  @links = Link.find(:all)
end
</pre>
<p>That will insert a link to admin/mootools-1.2-core-yc.js inside the admin/links/index page. Righto, so now the only thing left to do is get the mootools-1.2-core-yc.js file into the actual public/javascripts/admin directory within the project. What you want to do is alter the vendor/extensions/link_roll/link_roll_extension.rb file so that within the activate method the file is copied over. I&#8217;d recommend making a public/javascripts/admin directory within your extension folder, and putting the file in there. Then, when activate is called on the link_roll_extension.rb file, the activate method will copy the file over to the projects public/javascripts/admin directory. You should also delete the file when the deactivate method is called in the link_roll_extension.rb file.</p>
<p>Questions and comments please!</p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2008/08/15/radiant-cms-tutorial-custom-javascript-in-admin-pages/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Not all software is created equal</title>
		<link>http://hamishrickerby.com/2008/07/22/not-all-software-is-created-equal/</link>
		<comments>http://hamishrickerby.com/2008/07/22/not-all-software-is-created-equal/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 17:40:10 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[travel]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/?p=239</guid>
		<description><![CDATA[The types of companies I (used to) work for and (now) consult to,Â  love release management.Â  At least their IT people do. For those who are not in the know, check out the following 2 resources for a bit of background http://en.wikipedia.org/wiki/Software_release_life_cycle http://en.wikipedia.org/wiki/Release_Management When companies often start out, they focus on getting IT systems enhanced [...]]]></description>
			<content:encoded><![CDATA[<p>The types of companies I (used to) work for and (now) consult to,Â  love release management.Â  At least their IT people do.</p>
<p>For those who are not in the know, check out the following 2 resources for a bit of background</p>
<ul>
<li><a title="http://en.wikipedia.org/wiki/Software_release_life_cycle" href="http://en.wikipedia.org/wiki/Software_release_life_cycle" target="_blank">http://en.wikipedia.org/wiki/Software_release_life_cycle</a></li>
<li> <a title="http://en.wikipedia.org/wiki/Release_Management" href="http://en.wikipedia.org/wiki/Release_Management" target="_blank">http://en.wikipedia.org/wiki/Release_Management</a></li>
</ul>
<p>When companies often start out, they focus on getting IT systems enhanced as soon as possible.Â  A simplified, but common cycle is design (maybe), build (definitely), test (should) and deploy (definitely).Â  Steps in this process may be skipped when an organisation is small, and the side-effects of getting something wrong in build or deploy can be handled on-the-fly.Â  As companies mature and grow (in both size, application complexity, and IT landscape complexity), they often wish to have more control over the processes that manages software design, development and deployment.Â  As enhancements start to involve distributed application development (eg, introducing a new feature on a customer care system, that requires a service on a billing system, and have that exposed by an integration bus, and that integrated with from a web or <a title="IVR" href="http://en.wikipedia.org/wiki/Interactive_voice_response" target="_blank">IVR</a> channel), the process and dependencies involved with deploying that application become more complex.</p>
<p>To ensure that the cross system (and often) cross department, company or country design, development, test and deploy process, companies introduce Release Management Processes.Â  Different application development projects are collected together, and managed from a central point &#8211; who is unimaginatively known as the Release Manager.Â  The release manager usually has responsibility for delivery and deployment of all the changes requried within a system, and across systems for a particular instance of deployment activities (that&#8217;s a wordy way of saying that a whole load of stuff gets developed, tested, and then deployed together).</p>
<p>So, to recap &#8211; early days &#8211; applications designed, developed, tested and deployed whenever people want.Â  More mature business &#8211; applications designed, developed, tested and deployed under a managed process, with defined implementation dates.Â  In principle, that sounds fine.Â  In fact, it sounds like a sensible way to manage development and deployment.Â  Software can be complex, and complexity grows as you have more systems involved, different parties, different skills, and in some extreme cases, different countries and cultures.</p>
<p>Business users (ie, the people paying for the development, and specifying the functionality) rarely like release management.Â  It&#8217;s costly.Â  It&#8217;s slow.Â  It&#8217;s inflexible.Â  And this is more true if the business users know a little bit about software development, and <em>especially </em>if it involves the web.</p>
<p>The web is known for being an inherently agile environment.Â  Web applications are usually self-contained and loosely coupled, and can be easily and quickly altered.Â  There are other types of applications that exist in enterprises that do not have the same inherent agility.Â  Customer Management Systems, Billing Systems, Banking Systems, ERP systems.Â  All of these systems usually have long lead time on changes, strict testing requirements, are have historically been designed and developed in a different (monolithic) manner to web systems.Â Â  The requirements on them are often different too &#8211; they often aren&#8217;t about exposing new &#8220;services&#8221; to the public, but more about internal services, bug fixes, operational fixes, or enhancements to allow new products to be offered.Â  However, they don&#8217;t interface with the external customer and often aren&#8217;t driven by the same requirement for agility &#8211; it&#8217;s often easier in business (for your brand, and bottom line) to deploy something that is a bit crappy internally (manual processes, double-keying data etc) if you can get the message out to the customer.</p>
<p>Business users want the ability to alter the messages and functions that are delivered to their customers on their terms &#8211; when they want &#8211; not bound to some (in their eyes) arbitrary release schedule.Â  They don&#8217;t understand why their functionality must be deployed with another, completely unrelated, system or process.Â  They want to get their product to market.</p>
<p>I feel strongly that certain types of systems fall nicely in a &#8220;release managed&#8221; category, and others fall into a &#8220;system owner&#8221; managed category.Â  (sidenote: <em>I feel that for a platform that supports as much functionality as &#8220;the web&#8221; that often The System is too coarse a unit for splitting &#8211; it could be taken down to business process, journey, or user type</em>).Â  For me, I believe that systems that have a requirement to be highly agile, provide a high level of flexibility (configuration/scripting, as opposed to packaging and release of compiled code), and support essentially decoupled functions and flows, should not necessarily form part of conventional release management processes.Â  The &#8220;release early, release often&#8221; convention can be followed on these systems.Â  Obviously, a business must be made aware of the risks with this approach (e.g., more defects are likely to arise), and they should also be made aware of some of the sensible processes and changes in methodology to make this approach work (e.g., agile development methodologies).Â  In my mind, integration and web implementations fall into this category.</p>
<p>Integration systems enhance the ability for each system to remain decoupled from it&#8217;s peers &#8211; and this in turn means the systems are more modular, and should be able to support development and implementation (outside of a monster sized release), even when all of the required functions are not implemented.Â  Integration systems can provide stubs that indicate a service is unavailable, and when each system is finally ready, then the processes can be turned on in each.Â  Integration systems are inherently cross application, yet system independent at once.Â  This paradoxical view on integration is what makes them great candidates for exclusion from release cycles &#8211; they are self contained, but support both the situations where external systems are present, as well as when they aren&#8217;t.Â  This level of resilience and flexibility means that they are a core enabler to allow other systems to deploy functions, and still work when the up/downstream systems they are reliant on do not exist.</p>
<p>I have a couple of recommendations if yourÂ organizationÂ is considering looking to migrate to a release management style approach for application development and deployment:</p>
<ol>
<li>Applying release management only to systems where it makes sense to do so, will allow a business to maintain the necessary rigour required for financial, legal, regulatory, professional and moral obligations.Â  Release management should not be a one-size-fits-all approach.</li>
<li>Shielding systems with integration and process configuration flexibility (on/off switch for process/service enabling) will reduce the dependency of each system on it&#8217;s peers to be launched &#8211; and this in turn increases the flexibility to make changes to an individual system without them having a downstream impact, and increases the ability to more quickly make changes.</li>
<li>Applying a finer-grained design, build, test and deploy scope (i.e., not cross-system) to customer facing systems will give businesses the agility they desire to get their messages to market.Â  This in turn will allow businesses to try more products and services in the market, and respond to competition in a more timely manner.</li>
</ol>
<p>I believe following an approach that ensures that your systems are shielded from changes in each other, and promotes flexibility and agility in the customer facing systems is key to delivering true value to the business in terms of bothÂ responsiveness, and reliability.</p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2008/07/22/not-all-software-is-created-equal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open Source is a Meritocracy</title>
		<link>http://hamishrickerby.com/2008/02/08/open-source-is-a-meritocracy/</link>
		<comments>http://hamishrickerby.com/2008/02/08/open-source-is-a-meritocracy/#comments</comments>
		<pubDate>Fri, 08 Feb 2008 17:52:06 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/work/2008/02/08/open-source-is-a-meritocracy/</guid>
		<description><![CDATA[For those of you unfamiliar with the term&#8230; Meritocracy. CotÃ© from Redmonk quoted the title of this entry in episode 14 of Redmonk Radio. Again, it&#8217;s another quote that was like an &#8220;Oh yeah&#8221; moment for me. In companies where you produce software (usually) the project timeline or budget is king. In the open source [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you unfamiliar with the term&#8230;  <a href="http://en.wikipedia.org/wiki/Meritocracy">Meritocracy</a>.</p>
<p><a href="http://www.redmonk.com/cote/">CotÃ© from Redmonk</a> quoted the title of this entry in episode 14 of Redmonk Radio.  Again, it&#8217;s another quote that was like an &#8220;Oh yeah&#8221; moment for me.  In companies where you produce software (usually) the project timeline or budget is king.  In the open source movement, the best ideas take as long to get implemented as needed &#8211; there is no overriding time line that says you must ship that feature by this date.  Also, in distributed projects there can be healthy debate about the best way to implement things &#8211; the ideas and implementations with the best merit win.</p>
<p>I&#8217;m slowly catching up on these podcasts &#8211; making time on the train to listen is really working out for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2008/02/08/open-source-is-a-meritocracy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Coding vs Configuration &#8211; The vendors are missing the point, and the customers aren&#8217;t helping</title>
		<link>http://hamishrickerby.com/2008/02/08/coding-vs-configuration-the-vendors-are-missing-the-point-and-the-customers-arent-helping/</link>
		<comments>http://hamishrickerby.com/2008/02/08/coding-vs-configuration-the-vendors-are-missing-the-point-and-the-customers-arent-helping/#comments</comments>
		<pubDate>Fri, 08 Feb 2008 13:06:23 +0000</pubDate>
		<dc:creator>Hamish Rickerby</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://hamishrickerby.com/work/2008/02/08/coding-vs-configuration-the-vendors-are-missing-the-point-and-the-customers-arent-helping/</guid>
		<description><![CDATA[Large software vendors do (often in the long term) listen and act on what their customers say they want. However, implementations are still missing the point. What customers say they want and what they actually want can be very different things. Historically people (like me) in enterprises have harped on to vendors for years about [...]]]></description>
			<content:encoded><![CDATA[<p>Large software vendors do (often in the long term) listen and act on what their customers say they want.  However, implementations are still missing the point.  What customers say they want and what they actually want can be <em>very</em> different things.</p>
<p>Historically people (like me) in enterprises have harped on to vendors for years about how we want their large enterprise applications to be more configuration driven rather than coding driven.  The actual purpose behind this was about time to market, resource availability with the necessary skill sets required to maintain and alter the application, effort around testing and deployment, and certainty about the validity of the syntax and sensibility of the customisation.  Vendors have responded by closing the code base, but offering more complex configuration environments &#8211; which is exactly what we have asked for (see next paragraph about how we have asked for the changes).  However, what they have provided doesn&#8217;t meet the actual business goals of the request.  For example, I&#8217;ve been recently looking at some Product Configuration software that has a guided Java coding environment for rules definition.  This doesn&#8217;t actually make the implementation simpler.  It means that your (previously) relatively unskilled (and that&#8217;s flame bait if ever I&#8217;ve seen it) configuration staff have to significantly increase their skills to match those of java developers.  Its called &#8220;configuration&#8221; because its done in a &#8220;configuration&#8221; tool.  The configuration tool is as much a config tool as Eclipse is (which has code completion BTW, is equally applicable for the task, probably nicer to use and definitely cheaper).  What it&#8217;s done is moved the effort from the development staff, to the configuration staff.  Assuming staff are happy with what they do, developers are unlikely to want to join a &#8220;configuration&#8221; team, and configurators are unlikely to want to gain development skills.  One may also argue that your testing and deployment efforts are more difficult, because the coding that was done by people who know how to code, is now done by people who don&#8217;t know how to code &#8211; this in my mind introduces more risk.  You also don&#8217;t know which parts of the application are affected by this complex configuration activity, and this may drive for <span style="font-style: italic">more</span> rather than <span style="font-style: italic">less </span>regression testing.</p>
<p>I&#8217;ve also been reading recently about user stories, which are something I&#8217;ve never professionally come across.  I&#8217;ve been working for my entire professional career on waterfall based implementation projects, with requirements and scope specified in documentation like traditional UML use cases, interaction/sequence diagrams, and <a href="http://standards.ieee.org/reading/ieee/std_public/description/se/830-1998_desc.html" target="_blank">IEEE 830</a> style requirements.  I wonder if the large enterprise is its own worst enemy when it comes to vendor software direction and influence.  We are always writing (and that&#8217;s the first mistake) very specific (and that&#8217;s the second mistake) requirements for vendors to implement, and influencing them through RFIs and RFPs which contain hundreds or thousands of these requirements.  Maybe if the interaction was more conversation and (business) outcome based we&#8217;d actually get what we wanted, instead of getting what we write down &#8211; which is always going to be flawed (inaccurate, incomplete, technology based rather than business value based, and driving misunderstandings between reader and writer).  Conversations about outcomes are the way to get around the limitations of written software system specifications.</p>
<p>What we actually want and what we get are often different things.  I&#8217;m beginning to understand that outcome driven conversations between parties playing their specific roles are the way to go.  In a supplier-customer relationship, the customer should tell the supplier what they want to achieve (in a business context), perhaps explaining why the current implementation does not meet their needs.  The suppliers role is to understand the customers issues and the drivers behind why those issues are actually issues, and then propose ways those issues could be resolved.  Often it may be a process or simple usability issue, sometimes there are fundamental issues with the implementation that require longer term efforts to fix.  Regardless, the vendors know their software and the capabilities it possesses and the customers know their business drivers and understand how they are using the software.  Each party should focus on playing their part in the relationship and achieving their eventual outcome (customer = achieving the business value and business purpose they want, and vendor = getting a satisfied customer, which hopefully translates into a big purchase order for them).</p>
]]></content:encoded>
			<wfw:commentRss>http://hamishrickerby.com/2008/02/08/coding-vs-configuration-the-vendors-are-missing-the-point-and-the-customers-arent-helping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
