Thursday, October 02, 2008

Goalkeeper wanted!

It's off-topic, I know, but then I don't get much time to post anything at all right now, so here goes anyway.

Those who know me, know I'm a keen footballer. I play for a team in a midweek 11-a-side league, and we're currently DESPERATE for a goalie.

The matches are all on astroturf, so there's no studs and very few sliding tackles, and they vary in day, location and kick-off time as follows:

Very occasionally, we may have a match on a Wednesday or Thursday night at Market Road or Linford Christie Stadium but these are rare.

The team vary in ages between 20-ish to 40-ish, and there's a similar variance in abilities. No-one is anywhere near Ronaldo standard, put it that way.

If you're interested, email me directly (address is on the right, obscured for spambots) or add a comment at the bottom. We've got our next match on Monday, so don't hang about!

Wednesday, August 06, 2008

Holistic User Experience

SONAR v1.0 is just around the corner, and we've been thinking a lot about the user experience we offer. One of the key differences this time round is the recognition that User Experience is not just about the interface. Users in this sense are not just end users - they're *anyone* who interacts in any way with your software or your company. They include the sysadmins who have to install your stuff and keep it up and running, the managers who have to make a purchasing decision about whose software to spend their hard-won budget on.

So we believe that User Experience is about looking at the whole experience the user has in interacting with your software and you. It's about making the whole thing as easy as possible for them, right from the way they hear about it, through purchasing and finding the information they need to make an informed decision, through installation, configuration, administration, ongoing support, right the way through to migrating away from it if they want to.

Yes, I did say that you have to make it easy for them to migrate away from your
software. No, that's not a dumb thing to do.

There's two ways of looking at it - self-centred or user-centred. The first way often involves making it difficult to get their data out of your system once it's in there, end-of-lifing old versions and occasionally making new versions incompatible so that they have to keep buying your upgrades or they lose access to their data.

This is bad, m'kay? It's called Vendor Lock-In, and although it can do good things for your bottom line in the short term, ultimately it can create frustration and resentment among your users - Bad User Experience.

The thing to remember is that these days, people move around frequently. They change jobs, they change cities and countries at the drop of a hat, so if you create a Bad User Experience your bad reputation will spread along with the people who had it. The democratised web has created a situation where reputation has become more of a crucial commodity than ever before.

If you had to make a purchasing decision between system x and system y, and both of them had pretty much the same features for a pretty similar price, what factors would you use to make that decision? The first thing I'd do is ask around for anyone who's used either system before, and see what they thought of it. If I heard stories like "Yeah, it's OK, but once you buy it you're stuck with it" I'd hear alarm bells. I'm far more likely to go with a system that lets me get my data out easily if i change my mind for any reason.

You'd also look at questions like - whats the support like? Is there an active user community? Do they have forums / wikis / comprehensive FAQs? Do the reported bugs look they get fixed? Is it easy to find the information you need on the website?

You might give them a call to ask some questions, which opens up a whole new set of potential decision influencers - how quickly did they answer the phone? Did they sound happy to help? Did you have to navigate a labyrinthine set of automated menus for ten minutes before you actually got to speak to someone? Or even worse - did the menus have a voice recognition system that couldn't understand your accent?

All of the above factors - and many more - contribute to the user's experience of your company and your software, and all are potential factors that influence whether someone decides to spend their money on you. We know we've a long way to go in a lot of these areas, but we recognise this, and we're looking - and that's a great start.

Thursday, June 26, 2008

Atheistic Error Message Of The Day

while trying to install GOD, the Ruby process mgmt gem, I got a sudden attack of poignance:

[sonar@tryfan sonar-solr]$ gem install god
ERROR: While executing gem ... (Gem::RemoteSourceException)
HTTP Response 404


Discuss, in not less than 3000 words...

Thursday, April 03, 2008

Rake gotcha on Windows

We use Rake as our build system of choice for all of our projects, as it's much more flexible and pleasant to work with than make or ANT, and by and large it's pretty cross-platform. Except.....

I just spent about two hours tearing my hair out over something which should have worked transparently on Windows aswell as *NIX, but it just wasn't playing.

For reasons which would be tedious to go into, inside one particular rake task I needed to cd to a different directory and execute rake in there, to pick up a completely different set of tasks and ActiveRecord model classes, etc, and then resume execution of the containing task.

The following code worked fine on UNIX, but just completely failed to do anything on Windows:

Dir.chdir("../sonar-web") { system( "rake", "db:name_of_other_task" ) }


No error messages, nothing, it just wasn't doing anything.

I'll spare you the headbanging frustration and exhaustive list of things I tried that didn't work, and jump straight to the solution -

rake on Windows needs to execute c:/ruby/bin/rake.bat, not c:/ruby/bin/rake !

rake.bat will in turn call ruby.exe c:/ruby/bin/rake and pass on the command line parameters.

So at the top of my rakefile, I just added:

# on Windows, you can't invoke rake via a "system" cmd, as rake actually should invoke rake.bat
RAKE_CMD = RUBY_PLATFORM.match(/win/) ? "rake.bat" : "rake"


and then changed my system call to :

system( "#{RAKE_CMD}", "name_of_other_task" )

....and everything worked fine.

Tuesday, February 26, 2008

I still miss CFOUTPUT

It's been about a year now since I last coded CF in anger, and what coding I've done since then has been mainly in Java and Ruby On Rails. These days, most of my coding is done in my spare time, which is a resource in increasingly short supply - so coding actually tends to be done during my random bouts of insomnia. Like many similar turncoats, I've found RoR development to be settling into a fairly steady cycle :



  1. Do some really complicated stuff really quickly.

  2. Nod appreciatively and make coo-ing noises.

  3. Stop yourself just before standing up and announcing that your name is Boris and you are invincible

  4. Try to do something ostensibly simple, get stuck

  5. Spend ages scouring the web for the simple solution that surely must be out there somewhere

  6. Get pissed off because you found a blog post telling you that you shouldn't want to do that because it's "not the rails way"

  7. Figure out a really ugly cumbersome way of doing it step-by-step

  8. Fail to get to sleep because it's just bugging you that something so simple should be so hard in a framework that makes so many other more complicated things so simple

  9. Two days later, discover entirely by accident that the fifty lines of hackery could have been done in one long line of twenty method calls ( things.each do{ |foo| foo.do.some.other.thing }.and.then.do.some.thing.else( bar ) ) if only you'd known that the method you needed was called (insert counter-intuitive method name here) and that there was a plugin called (insert name of obscure plugin here)

  10. Go back and redo your hack with the one long line of twenty method calls. Feel like a l33t h4x0r d00d because you just replaced fifty lines with one.

  11. Discover that somewhere in your one long line of twenty method calls, one of them is returning nil.

  12. Think "hey, it's ok, I can debug this easily with the console!". Feel smug.

  13. Spend what seems like an aeon starting the console, reproducing the conditions in which you get your nil, changing something, then restarting the console so you can test your change.

  14. Resolve to write better unit tests in future.

  15. Pine a little for the good old days of "make your change then hit f5" to see if something works.

  16. Start a trawl through the source code looking for the cause of the problem

  17. Reflect that while duck typing is indeed an orgy of sheer loveliness, in this particular case it would be nice if just this once you could know for sure that this particular object is a Foo and therefore all you need to know would be found in foo.rb

  18. Discover that the cause of your woe is that at least one of your magical plugins doesn't work on Oracle, or SQL Server, or indeed anything other than MySQL.

  19. Go back to the blog on which you found the plugin to see if it's a known problem with a new version

  20. Discover that the blog is down.

  21. Write a plugin to patch the plugin to work on Oracle

  22. Feel vaguely uneasy that you now have a chain of umpteen plugins patching plugins patching plugins patching plugins patching ActiveRecord to do something that you apparently shouldn't want to do, but dammit, you needed to get it done by 5pm.

  23. Go out and pull scary faces at small children to make them cry for a while until you feel better.

  24. Come back feeling much better now that you've spread a little frustration around. Reflect that you're probably just not thinking about things in the "right" way.

  25. Adjust your thought-angle, and come at it again

  26. Repeat from step 1


To be clear, I do think that Ruby has some wonderful features. Blocks, open classes, method_missing - all of these little niceties make some fantastically cool things possible. The Enumerable#sort_by method in particular was one discovery that just gave me a wonderful warm fuzzy feeling - e.g.

some_collection.sort_by { |element| [ element.method1, element.method2, element.method3 ] }

Rails, also, has some really great features, and makes some of the donkey work so easy it's almost laughable. But sometimes it feels like all the thinking went into the elegance of the back-end design, and not enough thought went into the templating. RHTML feels like a tacked-on afterthought. HAML is better in some respects, but it still feels awkward. I haven't yet found any templating language that even comes close to the sheer simplicity and ease-of-use of CFOUTPUT.



The example that triggered this rant was grouped output. Let's keep this simple for the purpose of example - say I have a recordset with three fields:

























































Type Sub-type Title
Type 1 Sub-type 1 Foo 1
Type 1 Sub-type 1 Foo 2
Type 1 Sub-type 1 Foo 3
Type 1 Sub-type 2 Bar 1
Type 1 Sub-type 2 Bar 2
Type 1 Sub-type 2 Bar 3
Type 2 Sub-type 3 Foobar 1
Type 2 Sub-type 3 Foobar 2
Type 2 Sub-type 4 Foobar 3


- etc etc.



If you wanted to output these with headers and sub-headers whenever the type or sub-type changed, it would be almost trivially easy in CF:



<cfoutput query="myRecordset" group="type">
<h2>#myRecordset.type#</h2>
<cfoutput group="subtype">
<h3>#myRecordset.subtype#</h3>
<ul>
<cfoutput>
<li>#myRecordset.title#</li>
</cfoutput>
</ul>
</cfoutput>
</cfoutput>


- but in Rails? I'm still at step 5. I know I'm not the first person to need to do this, not by a long shot, but I just don't yet know what the method that surely must exist would be called. I know you can use Enumerable#group_by to group an array of
objects into something approximating the raw recordset above, but that's kind of working backwards to me.

I also know that someone will probably post the answer in a comment, probably with some kind of dismissive one-word instruction like "Read." or "Learn." linking to the relevant part of the docs. And that's all well and good. I'm just in a temporary bout of misty-eyed nostalgia for the things that CF made easy - particularly CFOUTPUT.

Friday, January 25, 2008

Don't Mention The War!

Well, in an office containing two Poles, two Germans, two Americans and many Brits, it had to happen sooner or later....

In response to an email about the petition for a Remembrance Day Bank Holiday, one of the Poles in the office said :
Personally I think it's a totally lame idea. People who want to go to Iraq and other remote places to shoot others should get a shrink not a holiday

At which one of the Brits said:
Hang on, what about the people who went to remote places like Poland and shot Germans?

And then the Poles started on about the lack of help they got in the early days of WWII, and just as that was kicking off, in walked one of the German guys.... and then the fun really started ...!

Ah, you can't beat a bit of good-natured dredging up national stereotypes from half a century ago to really get that Friday afternoon feeling into a place - it's still going, this is great, it's better than a movie! Where's the popcorn?

Wednesday, January 23, 2008

Ironically Apt Screenshot Of The Day

Tomasz was trying to install the Java Enterprise Edition SDK. For some strange reason it was only giving him this one single button....

Tuesday, January 22, 2008

A Question (or two) of Ethics (part 1)

A couple of thorny ethical questions have raised their head recently, and like most of these things, figuring out what's the "right" thing to do has not been easy.

The first situation came out of an interview. It's a classic problem - one that I've heard asked as a hypothetical "what would you do?" in interviews for a management post - but it does happen, and it happened to us.

We've been searching high and low for a damn good sysadmin, without much success, for months. We finally found a candidate with all the skills and a great attitude, he would have been absolutely perfect for us...  there was just one small niggle - in his younger days, he'd hacked into a major credit card provider. Not just for a look-see, either, he actually figured out a way to use people's credit card numbers without their accounts being charged, and used it.

He didn't really know how much he took in total, but in the end he turned himself in, and did hard time for it. Now a completely reformed character, he was looking for a job that used his obviously abundant skills in a positive way.

To his credit, he was very open about this, and he talked quite freely about it. We really liked him, and we were satisfied that he wouldn't be a security problem. However, then there's the matter of our customers.....

We do work for some pretty security-conscious clients. Some of them have US Top Secret classified projects. Although we were quite happy that this guy wouldn't be a security risk, would they be? We're a small startup, battling for contracts along with the rest, and it's hard enough at times to get big corporations to take you at all seriously even at the moment. Anyone who has ever jumped through the zillion flaming hoops that they put you through in order to get a whiff of business from these kinds of companies knows just how insane their security procedures can be. (I'm still smiling at the badge I had to wear on one site visit recently - big bold capital letters, red font - "FOREIGN PERSON! ESCORT REQUIRED!") If one of them got wind of us having a genuine time-served cracker working for us, we'd be dead in the water.

In the end we had to make the uncomfortable decision that we couldn't hire this guy, despite him being one of the best candidates we've had. We're still looking for a suitable sysadmin.

That was a few months ago. The second incident is much more recent - yesterday, in fact - and quite similar, it's kind of approaching the same question of reform and change, but from an opposite direction. Mind you, this post has gotten quite long, so I'll put that in a post of it's own.

Wednesday, January 09, 2008

Error Message Of The Day - Sharepoint

I love sharepoint.
It's great.

It's sooo easy to configure and debug.
And so nice and rewarding to use.