Skip to content
From my darling wife:

Well, folks, it's finally happening... the Hayes family is leaving town. We've been very happy here for the past nine years, though, and we're certainly not going to leave without saying goodbye!

We've decided on a date for a big going-away 'do, but we don't have a venue yet. (We've decided we're not quite crazy enough to have this one at home, especially with no furniture!) So here's the deal: you let us know if you're free, and we'll find a spot for us all to raise a glass together.

Date: Saturday, June 12
Time: Afternoon - maybe 2ish until 6ish?
Venue: TBD

Kids are welcome, just please let us know how many!

RSVP ASAP to this amanda.l.hayes@gmail.com. Here's hoping you can make it!

Much love,

Steve, Amanda and Jamie
While I normally blog about software development, today I'm going to blog about something much more personal, something that most of my friends probably don't know. The trigger is the debate on the right to assisted suicide in the UK and on the right to access even information about assisted suicide in Australia, which would be blocked by the proposed internet filter. While I won't be as articulate as Sir Terry Pratchett I want to present my personal experience.

I was in my mid-20s when my partner's mother, still in her 40s, was diagnosed with breast cancer. Even though she lived in Cairns, a rural centre, she received excellent care, including flights on the air ambulance to city hospitals when she needed them. That experience, and my own health issues growing up, cemented for me the importance of free national health care, but my brush with assisted suicide came towards the unfortunate end of the story.

Despite a radical masectomy and many other treatments the cancer spread to Margaret's bones, and eventually she deteroriated quite rapidly. One day we got a call that if we wanted to see Margaret alive we needed to come to Cairns, right away. My partner was in Melbourne, I was in Sydney, one of my partner's siblings was on a prawn trawler in the Gulf of Carpentaria, but we all dropped what we were doing and went to the airport. I remember walking out of the office, telling my boss that I was leaving right away and I didn't know when I would be back, and him simply replying "Ok, do what you need to do" (thanks for that Brian).

We all arrived in Cairns and started a vigil by Margaret's bedside. She was immobile - her bones were so weak and brittle that the nurses needed to be careful not to break them when they changed the bed - she had difficulty breathing, and she was very weak, but she lingered. She was pleased to see all her children, but it was obvious that she was unhappy and she was not going to get better. One morning she told us, in short breaths, that it was impossible to hold your breath until you died - she'd tried it the night before and it didn't work.

Margaret had been estranged from her husband before the cancer got very bad, but they had moved back in together to look after her and their youngest child, who was about 12. He was pretty rung out and wasn't really part of the decision-making around Margaret at the time. He was a diagnosed manic-depressive and we were concerned that he might commit suicide after Margaret died, so we talked about how to handle the care of the youngest child in those circumstances. We also needed to talk to Margaret about formalising her will (if you haven't, please do that now, as handling it on your deathbed is no fun for anyone). As the older partner of the oldest child, some of the responsibility for these things rested with me. Eventually the conversation also came around to Margaret's death. It was clear that she was ready to die, from both her actions and her words, and we could see that she might ask one of us to help her. What would we do? What would I do?

I don't know what everyone else thought. I think we talked about it without making any final decision as a family, but I also know that I made a decision in my own mind. If Margaret asked me to help end her life I would do whatever I could to help. I would do it with tears in my eyes (like the ones I have in my eyes now, writing about this more than 20 years later), but I would do it nonetheless. And it would be illegal, and I would bear the consequences - the legality or otherwise of the action made no difference to the decision and the act, though it might have made a considerable difference to my life.

Margaret peacefully and quietly passed away one night in her sleep, with her eldest daughter at her bedside.

Assisted suicide isn't a theoretical issue for me, it's a hard, practical one that I faced head-on, and having made that decision once I know that if the circumstances arose again I would make the same decision. I believe that as a caring and compassionate society we should be able to extend the right to die with dignity at the time (and if possible the place) of our own choosing to everyone. I believe that the benefits of providing that right outweighs the cost and effort of monitoring to make sure that the right is not abused.

Ruby on Rails’ opinionated attitude towards testing has introduced a lot of people to test driven development. Whether it’s because rails development has encouraged good testing practices, or because it has attracted pro-testing developers, rails (and ruby in general) now has a large ecosystem of testing and quality tools.

If you’re a rails developer, you’re probably already writing tests. You’re probably using RSpec or Shoulda (and also Cucumber, but I’m just talking about unit tests here). You’ve probably run your code through rcov, to see how well much code your tests cover, and you’ve probably also looked at other code quality metrics, like the ones generated by metric_fu (or a hosted service like codeyak).

Quality metrics for your code force you to write good code. They are an essential part of test-driven development, because in TDD our design is supposed to be driven by spotting code smells. Unless we think we can get the design (both in the macro and micro) correct first time (and we can’t), then we always have to be on the lookout for these code smells that will drive us to refactor and evolve the design into something better. Since I’m using words like “drive” and “force”, obviously I intend these metrics to be enforced. If you aren’t already doing it, start now.

The following example presumes that you’re testing with rspec, but it only requires slight modifications to make the rcov threshold work with other testing libraries.

First up, ensure that your app has the following gems installed (bundled):

metric_fu, flay, flog, reek, roodi, rspec, rcov

Then, grab my continuous integration rake tasks from here:

http://gist.github.com/364034

Finally, tell your continuous integration server to run “rake ci”. I use cruise_control.rb, but there are plenty to choose from.

You can modify the hash values in the THRESHOLDS constant to set the quality thresholds for your project. Set them so that they just pass at the moment, and then try to improve the code and slowly crank them tighter. For rcov that means raising it (towards 100.0), and for the others, that means lowering them.

Since you’re using metric_fu, you’ll also get graphs and pretty reports of the output. If you’re using cruise_control.rb, look for the “output” link in your build artifacts on the web interface. I’m not executing rcov via metric_fu in my code, because the metric_fu rcov task hides errors in the specs, and we also want the build to fail if a spec fails.

Many years ago I worked at Bankers Trust Australia, building derivative product applications with VMS Cobol for the user interface and Fortran for the numerically intensive parts. I mention the technology so that you can understand that this was the early days of the derivatives markets when there were only a few players in Australia, using relatively unsophisticated technology. I remember how proud we were of the first release, particularly of the way we validated all the user input and provided field-by-field feedback to the traders. Then I was lead into a trap.

"Wow, that validation is really impressive. It must have taken you quite a while to do that", said a trader.

"Yeah, it probably took a few weeks to get it all right", we replied.

"So you could have delivered it a few weeks earlier if you hadn't done that?"

"Yes, but the application would have crashed each time you made a mistake and you'd have had to start again", we said.

"We're pretty smart, and we can learnt to deal with that. Next time we'd rather have the features two weeks earlier so we can make some money from them thanks".

The underlying problem was that we hadn't talked to them about what was important (my excuse is that it was a long time ago and I was young and naive), but the lesson has stuck with me. In that situation, an input function vomiting it's guts on the screen was a scope issue, not a quality issue. In the years since I've regularly heard people say "we cut quality to go faster" or "we cut quality to finish earlier", but when I dig deeper I invariably hear that they altered the behaviour from the end-user perspective, and to me, a developer on a software project, that's cutting scope. I appreciate that other people with different perspectives might consider these features to be the difference between a high-quality or low-quality application, so when we start talking about "quality" we probably need to clearly understand which perspective we're talking about.

I was reminded of that by a recent post by Uncle Bob that starts with "People often make the argument that time to market is more important that quality. I’m not sure just what they mean by that. Do they mean that it’s ok if 20% of the features don’t work so long as they deliver quickly? If so, that’s just stupid.". I think that would be stupid, but what I think people mean is that the internal quality of the code has been sacrificed to reduce initial time to market, which is a very different proposition.
I'm supposed to be doing my US tax return right now, but I got distracted (what a surprise) and read this post from March 2009 by James Shore. At the end of the post James says two things that resonated strongly with me:


"If the point is to Be Agile, there's no need for Agile to actually work."

and

"Starting now, I'm reorienting my business to focus on people who want to be great."

Last night I said goodbye to me colleagues at Cogent Consulting, and one of the things that I meant to say but forgot was that for me interesting agile consulting work in Melbourne is now rare. I would have struggled to say why until I read James' post - I think it's that once-upon-a-time my consulting work was mostly with people who really wanted to be great, regardless of their current performance. It might not have been everyone in an organisation, but in each organisation it was enough people that greatness was the dominant theme. At some point those gigs dwindled - on the new gigs some people may have wanted to be great, but the team/division/company as a whole wasn't really interested. They pay lip-service to greatness, but it's the "we want to be great so long as we don't need to change too much of what we do" variety. My drive is to help people be great, and as that work has withered so has my passion. I may be willing to do work I'm passionate about for peanuts, but I think there's a thread in my mind which says if you can't give me work I'm passionate about then show me the money (and I think that makes me, well, human).

Now my soon-to-be-colleagues in Goldman Sachs may read this and shake their heads, so I need to be clear. I've always felt that enough of the people at GS wanted to be great to make working there worthwhile. It would be naive to think that it's everyone, everyday, but in my experience it's definitely enough. So I hope to have the pleasure of having my passion rekindle there as well.

I think this reinforces Cogent's recent decision on medium-term focus as well. The future of Cogent Consulting isn't to help other people with their agile transitions. The future is to blend Cogent's passion for software development with the needs of people who are passionate about their own domain, outside of software development. The result will be delivering excellent solutions that change people's lives - sometimes because no one else could do it economically, sometimes because no one else could build the partnerships that Cogent could build, and sometimes because no one else could do it at all.



Helping people transition to agile development - 10 years

Forming my own consulting company - 2.5 years

Finding outlets for my passion - a lifetime


** Updated 26/3/2010 **

If you read this blog regularly then you will know that I'm about to embark on a career change. Part of this will be moving from a relatively safe environment where I have a reputation (Melbourne) to a challenging environment where I'm a relative unknown (London). When I meet new people in London (professionally) I'd like to have something I can point people to that gives them some background and helps to set their expectations. I'm personally expecting to be meeting quite a few new people, and I hope that this can accelerate the familiarisation step a bit.

First, I'm incredibly introverted. I've learned to be vocal in some situations, but sometimes that confuses things because people don't notice just how introverted I really am. How does that manifest?




  • I'm pretty quiet in meetings


    Particularly if I don't know all the participants I tend to listen more than I speak. That doesn't mean that I'm not thinking about the matter, or that I'm not interested, it just means that I'm not talking :-)


  • I think slowly


    Sometimes experience gives me intuitive leaps, but I'm often the person who comes back the next day and says "that thing we talked about yesterday isn't going to work, and here's why". Even when my intuition gives me the right answer quickly it can still take me a while to come up with an explanation. When this happens it's not that I'm being uncooperative and trying to work outside the meeting/collaboration, it just means it look me a while to get to where I was going


  • I understand pairing gives better development results, but it doesn't come naturally to me


  • I'm unlikely to join you at the pub for a beer


    It doesn't mean I don't like you, but it's not an environment that suits me.


  • I'm not into public celebrations


    This can get me into trouble, especially when I'm meant to be "leading". It's not that I'm opposed to celebration, it's that it's not something that I volunteer for. If you happen to suggest my team needs one I'm likely to agree and ask you to arrange it!


  • I don't deal well with conflict, particularly if it happens quickly


  • I'm pretty analytical, but emotions can be a bit tricky for me. I need to gear myself up for situations where there might be conflict, and if one springs upon me unexpectedly I'll usually disengage. It's nothing clinical (empathising comes fairly easily to me), but it is something I've learned about myself.



I've managed to add a few layers to this introverted foundation. I'm a reasonable public speaker, I generally enjoy it, and I'm happy to talk about software development to any group that's interested.

I've been referred to as a "code quality freak". My attitude is that you should work on the micro-level details of programming until they've become muscle memory, so that you can free your brain up to work on the complicated stuff. This covers all the stuff you'd find in coding style guides and books like Bob Martin's Clean Code (though I have to fess up that I haven't read that yet). Even at the micro-level I like to use tools to tell me where I've let me standards slip, so I'm keen on tools like Simian, Checkstyle, Complexian and their equivalents in other languages. These days I'm also interested in visualisation of the output of these tools, though I don't have as much experience in that area.

Another metaphor I use around code quality is that it's like hygiene in a hospital - we shouldn't need to talk about it, we should just do it. If we can't maintain hygiene then everything else is going to get a lot, lot harder. Some people suggest that you can clean up your technical debt by having dedicated iterations - to me this is like suggested we let crap pile up around a hospital and clean up every couple of weeks. It doesn't work for me.

I love automation. I have a very small brain and I'd rather use it for processing than storage. Manual processes are slow, tedious and error prone - I want to get rid of them.

I don't think that software development is predominantly a technical problem, I think that in most cases it's a social problem - how to we organise the people and technology we have to delivery an effective solution as cheaply as possible. Commercial constraints demand creativity and make software development challenging.

I like agile practices and processes, but they are means to ends. I think that as humans we are all imperfect - we should accept that we make mistakes, but try to reduce the consequences of our mistakes and try not to make the same ones over and over again. We can continually improve, but to do that we need to continually reflect and continually learn. I'm very keen on the ideas emerging around expertise and deliberate practice.

I'm sure I'll think of more and extend this post, but there's a start :-)


I was updating a Rails app recently and found the tests weren't running.
The error was reported in HoboField (an ace gem that lets define your model fields within your model and auto-generate your migrations by 'diff'ing between schema and models).

The error was .../hobo_fields/field_declaration_dsl.rb:22 'field': wrong number of arguments (1 for 2)

This was being thrown when ruby was getting to a model class like this...


class SomeModel < ActiveRecord::Base
fields do
timestamps
end
...
end



The error turns out to be because the DSL class in Hobofields uses BlankSlate as it's base class. ActiveSupport also has a definition for BlankSlate, so Hobofields does an 'unless defined? BlankSlate' check before it defines one.

However... I was also using 'Riot' for my testing. Riot also defines BlankSlate.
The ActiveSupport version leaves the instance_eval method on the BlankSlate class. The Riot version removes it and doesn't check to see that BlankSlate is not already defined. Riot was accidentally Monkey Patching ActiveSupport.

As both libraries were being loaded, so the Riot definition was extending the ActiveSupport version and it was loosing it's instance_eval method. This leads to missing method picking up calls it shouldn't and eventually ends in the error I was getting.

I patched Riot and the problem went away. I expect to run into this sort of problem again in the future.

Do me a favor :) If you are developing a gem, please be really careful what you define in global space. It is best to namespace any classes you define so you don't risk cross over.

Thanks
We have been having this issue with Visual Studio 2010 Beta2. It just stops loading. For some it stops loading unless you load it via loading a solution, others it's the opposite.

We can't move to the RC2 until we it supports Silverlight 4 properly..

The solution?

We have had some success by just loading up a visual studio command prompt and running:
devenv /ResetSettings

UPDATE:
Also try:
devenv /reset
devenv /resetuserdata


Give it a go. Let me know how you get on :)
(It might also be worth backing up your currentsettings.xml file first)
I found this, a handwritten copy no less, while cleaning out a filing cabinet tonight. At the bottom I've written "Charlie Alfred, Education Services Manager, Object Design Inc, Object Magazine, May 1994". Apparently I've been carrying this around for almost 16 years. Since Google didn't find the article, I reproduce here for your pleasure (and so I can find it again myself).

Affinity for win/win



We strive to create an environment where the personal aspirations of each team member contribute to the goals of the team. We each are personally committed to achieving the goals of the team without sacrificing our lives outside work. We firmly believe that on the strongest teams the goals of the team agree with the goals of its members, rather than supersede them.

Common Mission



We share a common mission that is challenging, worthwhile, and clearly understood by all. This mission may be perceived by others as impossible or not worth the sacrifice. In this way, the mission helps us to identify our partners. Also, the more impossible the mission seems, the more we are forced to work together if we hope to succeed.

Quality



Quality is at the core of everything we do. If something is worth doing at all, it is worth doing right the first time.

Understanding Requirements



We strive to fully understand the requirements of the systems we plan to construct, including being acutely aware of how those requirements evolve over time. Furthermore, we actively validate our understanding of these requirements with the system's intended beneficiaries.

Interdependence



Individually, we each contribute strengths that counterbalance each other's weaknesses. Collectively we possess all of the skills, attitudes, and habits necessary for team success. Wherever an essential skill, attitude or habit is missing (or lacking), one or more of us makes it a priority to develop it, or we seek to add a new member who possesses it.

Receptivity



We are open to sources of new ideas and new ways of doing things, and use the norm to resolve conflict. We listen to each other's points of views, aware that our commitment to the same mission means that differences of opinion identify alternate paths to the same goal rather than competing paths to different goals. Also, we continually learn about and apply the latest paradigms, processes, and products in our technical, organisational and interpersonal activities.

Efficiency



Around here we work smarter, not necessarily harder. We sprint all out toward our goals when it is necessary to do so, but also know how to relax and rejuvenate. We make the 80/20 rule work for us. We take no shortcuts and cut no corners on the 20% of our tasks that produce 80% of our results. If any sacrifices must be made (in the interest of time), they always fall in the 80% of our activities that produce 20% of our results.

Thanks Charlie!
Many of you may have seen this already, but if you haven't I think it's an essential read. "Freedom and Responsibility Culture" describes how Netflix resolves the challenges involved in growing rapidly while maintaining a culture that supports rapid innovation and excellent execution. It's a good explanation of why they don't adopt the process-bound, complex-compensation approach that I see at many organisations. Some of what they do is consistent with what we do at Cogent, but some of it is radical even for me (for example, there is no vacation policy!). I wish I had read it earlier.