Thursday 6 December 2012

Link: Everything you need to know about the National Broadband Network

Hi all, this one is aimed at other Australians. Since it was first announced in 2009, there's been a lot of rumbling about the National Broadband Network plan - what it actually is, whether it's worth it, what it actually means for us or for the Australian budget etc etc

This link provides an article that fully explains what it's all about and is well worth a read.

The NBN: everything you need to know

TL;DR: it's a plan to replace the antiquated Telstra copper-network with high speed fibre (preferably to-the-home) so that we can keep up with the massive influx of bandwidth we're all using these days just like all the other high-tech countries did ages ago... and yes, it's worth it.

Friday 30 November 2012

Link: Why engineers are grumpy

There have been many great articles on how to deal with IT-folks. This is another of them: The care and feeding of software engineers (or, why engineers are grumpy)

It explains: what makes engineers tick, what makes them grumpy and why, and also solutions to make it all Just Work. It covers both the strengths and weaknesses of engineers, and how to build on the former, while avoiding the latter.

I'll leave you with a few quotes:

In almost every other industry where things are built, it is expected that all requirements and details are agreed upon and finalized before building commences. Except in software. In software there’s “not enough time” to gather all the requirements ahead of time. The importance of moving quickly is hammered into us from day one. And so engineers learn to fill in the gaps left by product managers just to keep the project going. Product managers, of course, also have the reputation for changing their minds frequently, which means engineers assumptions are often invalidated partway through the process. Is it any wonder that software engineers tend to burn out quickly and change jobs frequently?
True priorities aren’t transient, they are static. The frequency with which people above us change their minds is incredibly frustrating for software engineers. We frequently stand ready to march into battle and just want a direction to march in. But if you tell us one day that we’re building a house and the next day that we’re building a car, you should expect some dissension in the ranks.
There are few phrases that anger software engineers more than, “I used to code.” ... If I were to ask LeBron James how much time he needs to prepare for a game, I’m sure he’d be amused if I disagreed because I played basketball in high school. Software engineers get the equivalent all the time.
We software engineers are an interesting bunch. There’s a definite personality that comes along with us, and we really do want to make the best thing possible. If you stop treating us like short-order cooks and start treating us like part of the creative process, you are likely to get much farther, faster than you would otherwise. The teams on which I’ve worked have all had varying degrees of friction caused by not understanding the engineers’ mindset and what drives them. It’s my sincere hope that this article will lead to better communication between engineers and those that they work with. It’s really not that hard. We’re all just people who want to feel like a part of the solution rather than a worker bee.

Saturday 24 November 2012

Deleting un-named foreign keys in a migration

So, we use foreign-key constraints in our db. It's pretty annoying to get Rails to work nicely with that, but we have some basic helper methods (which I didn't write, so I cant share).

However I recently had some trouble dropping an old table. I kept getting these errors:

Mysql::Error: Error on rename of './mydbname/#sql-1ca8_f7842' to 
   './mydbname/my_table_name' (errno: 150): DROP INDEX `my_table_name_idx3` 
   ON my_table_name

I discovered that this was because it had foreign-key constraints. The awful error message is itself listed as a bug on mysql... but the real problem is that it doesn't want to drop an index I've asked it - because there's a foreign-key constraint on the column referenced by that index*.

Fair enough.

Unfortunately, the "remove_foreign_key" code we have assumes the foreign-key has been named in a certain way (table_name_column_name) but in this case it wasn't. So Trying a drop index on that caused it to give an equally unhelpful message along the same lines...

This foreign key has been hanging around since the dawn-o-time, and it has one of those automagically-generated constraint-names built by the db itself... something like: my_table_name_ibfk_16.

Now that'd be fine to drop if we just had one client. with one database... you can easily put the following into a migration:

   execute "ALTER TABLE `my_table_name` DROP FOREIGN KEY `my_table_name_ibfk_16`" 

Unfortunately for us, we have 150 clients - each with their own db... and it looks like that constraint-name differs depending on which order the foreign-keys got created. ie sometimes it's my_table_name_ibfk_16 and sometimes it's my_table_name_ibfk_3 - and if you drop it by number - you could be killing the WRONG foreign-key constraint... which would just be embarrassing.

The way out of this quandary is to query the information_schema table to find the foreign-key's actual constraint-name. and here it is for your amusement. (note: put this into initializers eg by saving it as config/initializers/migrations.rb

class ActiveRecord::Migration
  # grab the db-name out of the connection and persist it
  # it's not going to change over the course of a single migration
  def self.fetch_database_name
    @@database_name ||= connection.database_name
  end

  # Use this if the foreign-key was created without an explicit name - 
  # and has one of the automatically-generated constraint-names.
  #
  # This method queries the information-schema table to fetch out the key
  # name before continuing to drop the foreign-key
  #
  # Use this in your migrations with:
  #    remove_legacy_foreign_key :table_name, :field_name
  # eg:
  #    remove_legacy_foreign_key :widgets, :wodget_id
  def self.remove_legacy_foreign_key(table, column_name)
    # first pull the foreign-key name from the information schema
    result = execute "select constraint_name from information_schema.key_column_usage as ke where ke.table_schema = '#{fetch_database_name}' and ke.table_name = '#{table}' and ke.column_name = '#{column_name}';"
    name = result.fetch_hash['constraint_name']
    raise "Got no foreign key by that name" unless name.present?
    execute "ALTER TABLE `#{table}` DROP FOREIGN KEY `#{name}`"
  end
end

[*] Note: mysql also gives a similar error if you're dropping a foreign-key constraint that doesn't exist at all by the name you give it:

ERROR 1025 (HY000): Error on rename of './mydbname/my_table_name' to 
   './mydbname/#sql2-1ca8-f6cc5' (errno: 152)

Saturday 17 November 2012

Kiva is addictive

No IT angle today...

I have a mixed approach to giving to charity. I have a number of regular direct debits for various causes, and I also give sporadically in lump sums when inspiration strikes me.

My latest of these is Kiva (here's a Kiva invite) - which is a site that does micro-loans to people in developing countries.

Kiva has been on my radar for a while now, but I'd been putting it off because I had a few misconceptions about the whole process and I finally got down and actually did some reading on what it's all about.

I was mainly concerned by the fact that in most cases, the loans have already been given out, and you are paying for something that is already a fait accompli - which I thought was weird, and that it meant that you weren't really lending the money to the people you had chosen.

Turns out to make a bit more sense. These people need loans immediately, so the partner in that country does so, and then posts the loan up to Kiva. When you choose to "fund" that loan, your money then underwrites it. You are taking on the risk for the loan.

Now I've had it explained, it makes sense to me, so I've been having fun donating... it's a bit more addictive than I expected. I've already made five loans in as many countries, three of which have now been fully funded - one of which I was the final person that funded it (and that feels pretty good). We'll see how they go.

Thursday 8 November 2012

Link: Unit tests don't find bugs

A quick article called unit tests don't find bugs points out what unit tests are really for, and advises us not to forget that unit tests cannot be used as a substitute for QA-style testing.

Friday 2 November 2012

ruby gotcha: beware trailing commas

I had something like the following (though with more values):

 h = OrderedHash.new()
 h[:a] = {:a => 1}
 h[:b] = {:b => 2}, # note the trailing comma - oops
 h[:c] = {:c => 3}

and started getting errors telling me that h[:b] was an array, when I was expecting it to be a hash...

Here's what's actually happening (via irb):

>> a = {:a => 1}
=> {:a=>1}
>> b = {:b => 2},
?> c = {:c => 3}         # still part of the previous statement
=> [{:a=>1}, {:c=>3}] # so we end up with an array

Note to self: beware trailing commas

Saturday 27 October 2012

[SOLVED] undefined method `name' for "Ascii85":String

So, we're still using Rails 2.3.2 for our client... but I'm *trying* to upgrade it piece by piece. In doing so, I recently had to upgrade rubygems, so that it would work with a recent version of a gem we desperately needed.

Unfortunately it led to the undefined method `name' for "Ascii85":String bug that I wrote about when I last tried to upgrade rubygems

Back when it broke rubygems the first time, the only solution seemed to be to downgrade rubygems and hope for a future time when I could upgrade everything and get it working again.

But that wasn't an option this time... and so I had to hack up a solution.

The problem is described below in solution 2, but it's basically a problem with rails - which isn't using the newer rubygems gem-comparing "==" function properly any more.

Solution 1: Gem bundler

One solution that definitely works is to upgrade to using gem bundler (or the Rails2.3 version of bundler).

This definitely works because bundler doesn't have the same bug in it that Rails 2 has - it uses gem-comparison the new way.

But some of our clients aren't on the bundled release yet, and I need to quickly fix bugs and push to those clients... so I needed a solution that would let me still load the bundler-free version without having to downgrade rubygems to do it.

Solution 2: Fix rails

This solution requires a (very small) hack on Rails... but I figured that was ok as it was just to get my own system working so I can fix things without having to go through the pain of installing rvm (which I don't have time for right now).

So far the fix seems to be working, so I'll share (with the caveat that it's not well tested yet so YMMV).

The problem is really a Rails bug... not rubygems. So that's where you can safely hack (for now). From the stacktrace of the bug, find the copy of "rails/gem_dependency.rb" that is causing the issue:

/usr/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/rails/gem_dependency.rb:239:in `==': 
undefined method `name' for "Ascii85":String (NoMethodError)
 from /usr/local/lib/site_ruby/1.8/rubygems/dependency.rb:218:in `==='

In my case, I opened /usr/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/rails/gem_dependency.rb in a text editor (with sudo permissions). It'll have something like the following:

    def ==(other)
      self.name == other.name && self.requirement == other.requirement
    end

The actual problem occurs because Rails is sometimes passing the name already as a string to this function, instead of an actual spec. So to fix it, we just check for that with the following code:

    def ==(other)
      # The following line has been inserted to get around the bug:
      # "undefined method `name' for "Ascii85":String (NoMethodError)"
      return self.name == other if other.is_a?(String) # bugfix
      self.name == other.name && self.requirement == other.requirement
    end

It shouldn't alter existing functionality, it'll just get past the broken code that is in rails until you can upgrade rails, or use bundler.

If you (horror) actually need to install this fix on a live system; I'd recommend freezing rails to your gems directory before applying the fix. But in reality, I'd actually recommend just finding a way to upgrade to using bundler. It's a neater solution that won't require ongoing maintenance.

Sunday 21 October 2012

Link: Primer on sexism in the tech-industry

"The topic of sexism and its role in the technology industry has seen a huge resurgence over the past 12 to18 months. Yet despite being discussed and examined with increasing frequency, a lot of the subject remains unclear and under-explained, making it difficult for those who care deeply about our industry to partake in these discussions. This is, in part, because the problems are incredibly complex, nuanced and difficult to explain, making it impossible for any one article to address them sufficiently (lest that article becomes a book). Nevertheless, today we're going to try and see how much of the basics we can clear up."

Faruk Ateş has written a most-excellent primer on sexism in the tech industry

You should read this (especially if you are male) before even considering posting an article or comment about women in the tech industry.

Monday 15 October 2012

Making views/triggers/functions work in mysql for rails

We use mysql with Rails. We also use foreign-keys, views, triggers and stored procedures.

Rails's mysql gem still doesn't know how to handle any of the above yet... which is kind of inconvenient if you want to test your application.

The problem arises because even with a SQL schema dump - it only dumps the tables and foreign keys. No views, no triggers, no stored procedures. If you have code that relies on these... your application starts getting MySql errors.

Luckily there seems to be a solution with the db_structure_ext gem, which I've been using happily now for a couple of weeks.

I found the README isn't at all clear as to how to get it set up, so here's some basic instructions on how I made it work with MySQL on Rails 2.3.X

1) Install it as per the README:

gem install db_structure_ext and/or add gem 'db_structure_ext' to Gemfile and then bundle install

2) require it in your Rakefile

# extended db-structure-dump (also does triggers, routines etc)
require 'db_structure_ext/tasks'

3) Monkey-patch ActiveRecord

Create a file call config/initializers/mysql_adapter.rb (or similar) and add the following code:


module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter
      require 'db_structure_ext/init_mysql_adapter'

      # This is an overridden implementation of the structure_dump so that the
      # rake take db:structure:dump will dump out the schema elements.
      def structure_dump
        connection_proxy = DbStructureExt::MysqlConnectionProxy.new(ActiveRecord::Base.connection)
        connection_proxy.structure_dump
      end

    end
  end
end

You need this so that Active Record actually extends the new methods. If you don't do this, then you can call "structure_dump" yourself in your code, independently for certain tables. But the new functionality won't come through as the default for all of your db tables unless you extend MysqlAdapter as per above.

Tuesday 9 October 2012

Link: Women at work in Silicon Valley

Balancing work with family is one of the Hard Problems of Social Engineering a career... especially if you're female, and already suffer from several disadvantages in a high-tech workplace.

This article on The Guardian gives a great overview about how women in Silicon valley are making "Women at work" work.

Thursday 27 September 2012

Link: Amazon Review-spoofing scandal

This is a lesson in how any system can be gamed.

Amazon reviews have been built up to be an integral part of how we evaluate books for sale on amazon. The ability to see what people are saying about a product has turned the process of book-buying on its head. Instead of briefly skimming the back of the jacket and taking a gamble on whether it's good or not, you can see the general consensus of the community of readers and *hopefully* get a better idea on whether this book is any good.

Unfortunately, like any process, it can be gamed, and this week we've seen how deep this can get.

A guy called Rutherford set up a review-buying service where authors could come and purchase good-reviews on amazon. In one case making a new author (John Locke) into an overnight millionaire.

Here's a link to the full story on the John Locke book review scandal

The uproar in the authorial world has been tremendous. and amazon are investigating what happened and what they can do about it. It's a tough job, because it's extremely difficult to figure out whether reviews are sincere.

Hopefully they can find a way because I'd hate to lose the ability to see the true measure of the community's feelings towards a book.

Friday 21 September 2012

Link: count vs length vs size in Rails

Every now and then I have to remind myself of the differences between "count", "length" and "size" in Rails. I've never found a better source for this than the has_many :through article: count vs length vs size

It's well worth a read, even if you're an old Rails pro.

Saturday 15 September 2012

make will_paginate always show matches/pages summary

will_paginate is the standard pagination plugin for many a Rails-2 site, and it's extremely flexible.

However it has one drawback: it will only show links - if there is more than one page.

This is mostly not a problem, if the links are all you show. But lets say you also use it to show the "Showing 26 to 50 of 342 matches" summary. Then lets say you want it to show "Showing 1 to 16 of 16 matches" - even when there's only a single page (for the sake of UI consistency). will_paginate does not provide an option for this.

There's talk of adding a :show_always => true option to will_paginate, but last I looked it hadn't been dragged into master...

So I wrote my own monkey-patch.

You'll need to put the following two snippets into config/intiializers/will_paginate.rb


The first thing you need to do, is make the "summary" sections public, so they are available to the renderer (which is the thing that generates all the page-links for you). Here's mine (both scavenged and adapted from the web many years ago):

module WillPaginate
  class LinkRenderer
    # generates eg: "1 - 15 of 15" or "26 - 50 of 342"
    def matches_summary
      if 0 == @collection.total_entries
        # because "0 - 0 of 0" is a bit much
        summary_text = "0 Matches"
      elsif 1 == @collection.total_entries
        summary_text = "1 Match"
      else
        summary_text = "%d - %d of %d" % [ @collection.offset + 1, 
               @collection.offset + @collection.length, @collection.total_entries ]
      end
      page_span(1, summary_text, :class => "summary")
    end    
 
    # generates "Page 4 of 62" or "Page 1 of 1"
    def pages_summary
      if 0 == @collection.total_pages
        # because "Page 0 of 0" is a bit much
        summary_text = "0 Pages"
      elsif 1 == @collection.total_pages
        summary_text = "1 Page"
      else
        summary_text = "Page %d of %d" % [ current_page, @collection.total_pages ]
      end
      page_span(1, summary_text, :class => "summary")
    end    
  end # LinkRenderer class
end # WillPaginate module

And this chunk is what makes will_paginate:

  1. Accept the ":show-always => true" option
  2. If the above is passed, and there are no page-links... displays the summaries
module WillPaginate
  module ViewHelpers
    # This lets us still use any will_paginate passed-in renderers if we want
    # adapted by code in original will_paginate
    def fetch_renderer(renderer)
      case renderer
      when String
        renderer.to_s.constantize.new
      when Class
        renderer.new
      else
        renderer
      end
    end

    # don't lose the old will_paginate
    alias :old_will_paginate :will_paginate

    # overload actual will_paginate call to allow us to choose to show the 
    # "number of matches" box even if there is only one page
    def will_paginate(collection, options = {})
      # strip out the show_always option
      show_always = options.delete(:show_always)

      # do standard pagination
      html = old_will_paginate(collection,options)

      # if we didn't get anything, but we have "show always" = true
      if html.nil? && show_always
        # set up the renderer (stolen directly from standard will_paginate)
        options[:container] = true
        renderer = fetch_renderer(options[:renderer])
        renderer.prepare collection, options, self

        # produce the "matches" boxes through the renderer
        links = [renderer.matches_summary, renderer.pages_summary]

        # generate the html for the pagination links - 
        # default the html-attributes to the plain pagination class
        html = content_tag(:div, links, (renderer.html_attributes||{}).merge(:class => 'pagination'))
      end

      html
    end

  end
end

Then you can call it with this:

   <%= will_paginate @things, :show_always => true %>

Monday 10 September 2012

Link: 6 home truths about rockstar developers

We all want to hire a team of rockstar developers don't we? after all - with a team of rockstars our project will be the Best Thing Evar! ...or maybe not?

6 home truths about rockstar developers brings us back down to earth and points out the downsides of having a team formed of purely "rockstar" types. Worth a read - whether you're a hiring manager, or a rockstar yourself.

Saturday 1 September 2012

validate_format_of with better test-names

validate_format_of is almost always called more than once on a single fieldname. Generally with different valid formats... and then with different invalid formats.

eg our set of date-format validations:

  # validate_our_date_format(:end_date, "Please enter correct format for end date")
  def self.validate_our_date_format(field_name,msg)
    # /^[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{4}$/
    # dates we do match and should
    should validate_format_of(field_name).with('01/04/2010').with_message(msg)
    should validate_format_of(field_name).with('31/12/2012').with_message(msg)
    should validate_format_of(field_name).with(' 03/08/2010 ').with_message(msg)
    should validate_format_of(field_name).with('01/02/12').with_message(msg)
    should validate_format_of(field_name).with('02-01-2010').with_message(msg)
    should validate_format_of(field_name).with('1/2/2012').with_message(msg)
    should validate_format_of(field_name).with("04/10/2011\t\n").with_message(msg)
    # dates we don't match and shouldn't
    should validate_format_of(field_name).not_with('42/99/9999').with_message(msg)
    should validate_format_of(field_name).not_with('00/00/0000').with_message(msg)
    should validate_format_of(field_name).not_with('1').with_message(msg)
    should validate_format_of(field_name).not_with('abcd').with_message(msg)
    should validate_format_of(field_name).not_with('01/02/silly').with_message(msg)
  end

but there's a bug in validates_format_of... the description (which becomes the test name) is based on the following code: "{attribute} have a valid format" which makes tests named eg: "should :end_date have a valid format"... These test names are identical, not very useful, and not even properly grammatical.

*ALL* of them are named this eg, in the above example I'd have 12 tests all named as above...

At best, this identical-ness causes scads of Giant Flaming WARNINGS saying that
WARNING: 'test: <your enclosing scope here> should <fieldname> have a valid format.' is already defined
At worst, in certain (old) versions of rails - this means that only the first one gets run at all!

So - uniquifying the name is a Good Thing

The non-usefulness is that even if they do run, you don't know *which* version of your validates_format_of failed... because they're all named the same thing.

Thus this monkey-patch, which puts such things as the test-string *in the description*.

As with my previous shoulda backports, add these to a file in the config/initializers directory

module Shoulda # :nodoc:
  module ActiveRecord
    module Matchers

      # uniquify the description for validates_format_of "should" tests
      class NewValidateFormatOfMatcher < ValidateFormatOfMatcher
        
        # put a little more detail into the description
        def description
          if @value_to_fail
            "not accept #{@value_to_fail} as a valid format for #{@attribute}"
          elsif @value_to_pass
            "accept #{@value_to_pass} as a valid format for #{@attribute}"
          else
            super
          end
        end

      end
      # and override validate_format_of to use our new class
      def validate_format_of(attr)
        NewValidateFormatOfMatcher.new(attr)
      end
    end
  end
end

Note: this monkeypatch is for shoulda version 2.11.1 - not the latest Rails 3 version. You may need to modify accordingly if you're actually up-to-date...

Sunday 26 August 2012

Rails: five year plan?

My workplace is putting a tender out to a government body, hoping to secure some work for a big development happening soon.

As part of the tender process, they asked us what is the five-year plan for the development of the Rails platform.

Keeping in mind that 37Signals' approach to planning is "don't - it's all fiction anyway", we still had to provide them with an answer... and this is what I came up with.


Asking for a five year plan is a question with a hidden assumption. What you *really* want to know is:

am I going to get stuck with a dead duck?

I think the nightmare scenario you're trying to avoid is that you'll get maybe 1-2 years down the line, have spent a lot of money on changing your system over to the new-fangled software, only for the Software Vendor to go bankrupt and leave you hanging in the air.

Suddenly you lose any support if things go wrong. Bugs are found, but you've got nobody to call to fix them and you certainly won't be seeing any new features. hackers might find a new security vulnerability and there'll be nobody on the front-line to patch that hole and stop them getting to your protected data.

You're in a bad, bad place.

Thankfully, this scenario can't happen with Ruby on Rails (RoR), due to its Open Source Nature.

RoR was originally developed by a company called 37signals - but unlike a proprietary product, 37signals doesn't own the codebase, because they gave it away to the community.

It takes a little while to wrap your head around how that changes things, and most people will instinctively think that this means less accountability, less power and less security - when actually the opposite is true... so bear with me as I compare this situation against what you might be used to with a proprietary vendor such as Microsoft's .Net

Microsoft own .Net they also keep all the code locked away so you can't see it and don't really know what goes on under the hood. They make all the design decisions, but they also make all the decisions about what gets fixed and when.

So, if you spot a bug in the code - you have to go ask Microsoft (nicely, and generally after waiting a long time on hold) to please fix it for you... If they say yes - it goes onto the end of a very long support queue for their team of developers to prioritise against all the other features and bugs they've had pour in over the last several years. and if they say no - you have no recourse. There's nobody else but Microsoft that can fix it for you.

You can complain about it - which will also get ignored.

If you have an SLA with them you can call and tell them to do it now... which *might* change their mind... but if things go sour - nothing on earth will persuade them to do anything. and your only recourse would be to take them to court...
and of course we all know that if it gets to court you've already both lost, you're just hoping to recoup some of the damages. Better to avoid the whole thing in the first place.

The short answer is that all the power lies in the hands of Microsoft, and you are reduced to a supplicant throwing yourself upon their mercy.

By comparison, RoR presents a very different picture.

As I mentioned before, 37signals doesn't own the code. If you have a copy of Rails, you do, and so do we, and so does everybody else that is using Rails.

This changes everything.

If 37signals goes bankrupt... there is still a huge community of people using (and contributing) to the development of Rails... and even if every single one of them goes bankrupt too - you still have a copy of it yourself. So if you need to fix a bug or patch a security hole - you have the code in your own hands and can do it yourself or get somebody like us to do it for you. Same thing for new features or even just customisations to make it work more like you'd wish it would.

The power-balance is radically different - you are the one with all the control.

Luckily I don't see 37signals going under any time soon. Rails was released in July 2004, and went 1.0 in 2005 and since then it has moved on from being an obscure platform used only by web-geeks and enthusiasts like me, to being enthusiastically embraced by a huge variety of businesses worldwide.

Rails has recently undergone a Major Upgrade with the release of Version 3.0 - totally overhauling and improving the structure of the framework to meet the ever-changing demands of the web world, along with security and performance improvements.

Meanwhile, Rails 2 is still strongly supported by the community - as many businesses are still using it, and it will continue to be supported until there is no-one left using it anymore This stands in stark contrast to the dire fate of obsolete Microsoft platforms - which Microsoft rigorously cuts off after a small number of months, stranding anybody left behind without support - or forcing them to pay huge re-licensing fees to upgrade to the newer version.

Rails is free, including all upgrades to new versions, so you can afford to stay on the bleeding edge as soon as you'd like to.

Even if 37signals drops support for an older version of Rails - the fact that the codebase is out there in the community means it remains alive and supported as long as the community remains. And that community is very big, and very active.

There are roughly 2000 active contributors to the rails-core codebase, including myself, and all of them are herded along by the rails-core team - a set of 12 developers, most of whom are currently employed full-time by 37signals to coordinate contributions.

What this means is that even if all of 37signals were suddenly wiped off the planet by a stray meteorite, there are still 1988 very active developers who are willing and able to continue developing the codebase... and not just minor enhancements and customisations of small side-features either, even my own contribution (while small) was a change to one of the fundamental core classes of Rails. While developers such as Yehuda Katz have overhauled the basic mechanics of the whole system (for the better, of course).
and there's nothing stopping you from making changes like this yourself at any time for the forseeable future - if you ever see a need.
Open Source means it's all available to you, all the time... forever.

Imagine trying to change something fundamental in one of Microsoft's products all by yourself... you wouldn't even get the chance because you don't have access to the code to even look at what's inside.

One final aspect that I'm sure is on your mind is security.

You're probably used to a big vendor taking responsibility for checking that the system is secure from hackers and fixing any security holes as they come up, and are wondering what happens with a scattered base of developers and code.

Again, I'll compare with Microsoft.
They're probably one of the biggest vendors on the planet, and they make a big noise about how secure their code is... and yet every week or two we hear about a new virus or worm exploiting a vulnerability in Windows.
Big Vendors make a big noise - but they actually can't guarantee security, however much they'd like you to think so.

So what can you get?

You can get an active community of developers continually testing the software for vulnerabilities and being responsive and timely in fixing any newfound holes.

and RoR has that in spades.

In fact, it's much better at it than an in-house development team like Microsoft. The reason being that shift in power-balance I mentioned earlier, coupled with the wider community base.

If a security hole is pointed out to Microsoft, it goes into the queue and *eventually* one of their developers gets a chance to look at it. Maybe it's fixed, or maybe Microsoft decides it's not important enough to fix because it's only affecting one customer so it's not worth their while... of course if that customer is you, then this decision is catastrophic, but given that Microsoft has all the power - there's nothing you can do about it.

With RoR, however, the power is all in your hands. You submit the bug-report to the community and chances are, somebody else is either experiencing the problem or also concerned about it affecting them. Given the size of the community, this means there's ten times the number of people available to fix the problem as with the in-house Microsoft developers team - and many of them are personally motivated to get the bug fixed because it affects their business too.

But even if nobody else in the world is affected by this but you - you can still get it fixed yourself - because you have the codebase, and you have access to developers that can get it done.
Something you simply can't do with proprietary code.

Far more likely, though, is that if you have a problem - then everybody else does too, so you announce the problem to the community, who picks it up and gets it solved and submits it back to the community for everybody to share... including you.

Sure, you don't have one company to smack with a stick if something doesn't get done... but you will actually find that you'll never be in that position in the first place - because there's always a better alternative.

and don't forget that with a bigger community - that's more people to find and fix bugs and security holes - before you even got to Rails in the first place. The Rails community has more collective eyeballs on the code than Microsoft can employ, and more eyeballs means more bugs spotted and therefore fixed.

So as a quick comparison:

Vendor-owned proprietary system: RoR and Open Source approach:
lock-in
- they choose when you upgrade
- restricted backwards compatibility
- you *must* upgrade or lose the software
Freedom
- you are free to upgrade when you want *if* you want
- it costs you nothing when you want to upgrade - you can afford to be on the bleeding edge
- support continues as long as people are using it
- or you can pay somebody to fix it for you whenever
They keep all the power
- bugs and holes are fixed when they want (or not at all) according to their own profitability
- features are only added if they think they can make a profit out of it
You have all the power
- bugs and holes are fixed by the community when they need fixing
- features are added on the fly by anybody that wants/needs them - you can add them yourself if you like
Security-by-obscurity
- only a few people get to look at the code, which means only a few people get to check that it works correctly. holes are more likely to be found by exploiters than by developers which means the first you hear of it is when somebody hacks your system
- holes are fixed if the vendor has time and only if they think it's worth the money they spend on it
Security through openness
- a hundred thousand eyeballs on the code means security holes are more likely to be spotted by developers and fixed before they even become a problem
- holes are fixed as soon as they become a problem - because the people fixing them are the people that are affected by the problem that are actually concerned about security rather than just the profitability.
Conclusion:
The software lives and dies with the vendor Even if the vendor dies, the community lives on and therefore so does the code. So you never get stuck with a dead duck.

Monday 20 August 2012

shoulda: ensure_length_of.integer_field and associations with foreign key fields

We're still using Rails 2.3.X and therefore are stuck with thoughtbot-shoulda version 2.11.1 Which unfortunately doesn't come with a lot of the niceties of the most recent version. We've pulled some backports into our initializers directory to bring it up to speed - notably the ability to deal with foreign keys on association-definitions (see below).

But there's one small thing that has always annoyed me about shoulda - and isn't in any version.

That's the ability for ensure_length_of (the validates_length_of macro) to handle integer fields. Active Record can deal with it... therefore shoulda should too.

It's a tiny hack, but I'm currently too lazy to fork shoulda and write the tests to make it a viable pull-request, but here's a monkeypatch that'll get it working for you.

Save it into something like: config/initializers/shoulda_monkeypatches.rb, then use it like this:

   should ensure_length_of(:my_integer).integer_field.is_equal_to(4)
module Shoulda # :nodoc:
  module ActiveRecord
    module Matchers

      # I don't like it that ensure length of only works for strings.
      # This patch makes it also work for integers if we want
      class NewEnsureLengthOfMatcher < EnsureLengthOfMatcher
        def integer_field
          @integer_field = true
          self
        end      

        # re-write "string_of_length" to make the string an int-string
        def string_of_length(length)
          if @integer_field
            '1' * length # yep, this works for an int field
          else
            'x' * length
          end
        end
        
      end      
      # and override ensure_length_of to use our new class
      def ensure_length_of(attr)
        NewEnsureLengthOfMatcher.new(attr)
      end
    end
  end
end

Oh, and for the foreign-key backport:

module Shoulda # :nodoc:
  module Matchers
    module ActiveRecord
      # use the actual foreign key for an association
      class AssociationMatcher
        def foreign_key
          if foreign_key_reflection
            if foreign_key_reflection.respond_to?(:foreign_key)
              foreign_key_reflection.foreign_key.to_s
            else
              foreign_key_reflection.primary_key_name.to_s
            end
          end
        end      
      end      
    end
  end
end

Friday 10 August 2012

Link: 10 things i hate about git

The more I use git, the more I miss subversion... my own head-slapping confusion atm comes from it's inability to do what I would consider quite a simple merge.

Exactly why does it create a merge-conflict for something like this:

class Widget < ActiveRecord::Base
  has_many :wodget
  belongs_to :product_image
<<<<<<< HEAD

  def to_s
    name
  end

=======
>>>>>>> master
end

Or even worse:

class Wodget < ActiveRecord::Base
  set_table_name :some_table_item
  
  has_many :invoice_items
  has_many :comments

<<<<<<< HEAD
  
     
  
  
=======
>>>>>>> master
end

I mean, really?

So in frustration, I typed "why is git so stupid" into the google bar (as you do), and came across this lovely link to 10 things I hate about git which resonates perfectly with my current mood.

Go have a look - they're all excellent reasons.

I'm sure git has many wonderful qualities, but right now, I'm not feeling the love.

Saturday 4 August 2012

Link: vooza.com

"a mobile web app that is realtime, cloud-based, social and local... we're still in beta (have been for about four years now)... so we don't know what it does yet, but it will probably be like Pinterest or Instagram, but for weddings or sandwiches or something..."

vooza.com

Actually had me laughing out loud... I recommend watching to oldest-newest

"we prefer to think of revenue as a journey, not a destination"

Sunday 29 July 2012

Link: Painless Merge Conflict Resolution in git

Just sharing a quick link today, because I found Painless Merge Conflict Resolution in git to be an extremely useful, descriptive article on resolving merge conflicts in git.

Monday 23 July 2012

Javascript - so unobtrusive I can't even find it

Ok, so, what's the problem with obtrusive javascript?

Near as I can tell: it's a bit messy having all your js intertwingled with the html. Much like the once-dreaded embedded font tags - for which stylesheets were a wonderful invention. They pulled everything out of the way and kept them in one place , which cleaned things up a lot.

Enter: unobtrusive Javascript. Your JS is tucked away neatly, and placed onto your active DOM objects via id-tags et al - just like your stylesheet.

What are the down sides?

Well - lets say there's some magic JS doing something with the Foo element on your page... only there's a bug in it and it needs fixing ASAP. But all I know is which part of the page is being updated - I have no idea where the JS is located. The KS-functionality appears like magic from.... somewhere.

Lets complicate things (like real life) and say I'm new to the project, and the previous developer quit and is now living on a beach somewhere in a non-extradition country... so I can't ask them.

How do I actually *find* the JS that is unobtrusively messing with my html element?

It's ok if there's just one JS file that does a few things, or if you have a JS file per HTML page or some other sensible way of finding out which JS belongs on what page... but if you're coming onto the typical legacy project, you've got dozens of JS files with uncommented JS code for adding, removing, showing, hiding, dragging, dropping elements willy nilly - some of which are no longer used and who have useful, non-unique names like "move_stuff" or "display_items".

Sure, I can grep across the project for the ID of the html-element in question... unless the JS is operating on it via the DOM (eg every second child element of a td from a table that's inside the third div from the left...). But it's a little awkward.

There's also one other problem. Let's say I *don't* happen to know there's any JS operating on this element, and I update the html without even realising there's some accompanying JS to update (remember, I'm new to the team, and the former developer wasn't much for commenting).

Now the html and JS are out of synch. The JS is almost certainly broken, because I've just moved that html element into the second div from the left and nested it inside another table... and I will never know it was supposed to "display_items" then "move_stuff"... until Joe Random User suddenly notices that he can't submit the end-of-year accounting because the submit button no longer magically appears when he's finished filling out and validating the form (or whatever).

Clearly there are some benefits of the JS being tucked away out of sight (it looks prettier, which makes the html easier to maintain) but there are also clearly some disadvantages (it makes the JS itself difficult to maintain - two separate files mean a synchronisation-problem).

So, what's the solution?

As ever in design for computers, there's a balance/tradeoff involved, and your decision will probably involve a sightly different balance to what we do.

Personally, I like keeping the JS alongside the HTML it operates on. Sure, don't have it entangled in the html, but you *can* have your JS near the html that it relates to and still have it take into account the aspects of unobtrusive JS. ie the JS still adds to your HTML elements by using ids and DOM-paths... but the actual JS is either in the same template as the HTML (at top of bottom of the file), or is in a partial that's included into that template - so you always know it's there.

I'm sure it's far from the "perfect" solution... but it works for me, and makes it less likely that I suffer from the two problems outlined above, ie that I:

  1. can't find related javascript
  2. don't actually realise there *is* related javascript to keep in synch

What solutions do you use?

Tuesday 17 July 2012

Link: On technical entitlement

A Post by Tess Rinearson called On technical entitlement, has provoked a bit of a stir in reddit.

Apparently some posters consider to to somehow be emasculating... which is ironic, as the whole point of the article is to show how the behaviours of some people in the industry has an effect of destroying self confidence... and not just for women.

In my mind the only reason why the "women in tech meme" (as one commenter complained about) even shows up in the article is because the poster just happens to be female and it was a convenient example of the *general* problem that tech-entitlement seems to cause.

I think the discussion has been blown way out of proportion to the original article - which is an interesting look on one way that we can all think about our own behaviour (me included) to help newbies to the field feel more comfortable with being the beginners they are (and are allowed to be!).

What I took out of the article is that next time I meet somebody who's new to comp sci - I shouldn't try and "impress them" with my own l33t skillz to make myself seem big. Because often all that succeeds in doing is to make somebody else feel inferior - and that's *NEVER* a good thing. Instead try to encourage their own love of problem-solving ability, starting from where they are right now.

Wednesday 4 July 2012

Snippet: Array#to_hash

I've been finding this quite useful - especially when partition just isn't enough:

    def to_hash(&block)
      return {nil => self} unless block_given?
      the_hash = {}
      self.each do |val|
        key = block.call(val)
        the_hash[key] ||= []
        the_hash[key] << val
      end
      the_hash
    end

Usage examples:

   [1,2,3,4,5,6].to_hash {|v| v % 3 }
    => {0=>[3,6], 1=>[1, 4], 2=>[2, 5]}
   Widget.all.to_hash {|w| w.status }
    => {:pending => [<Widget1>,<Widget4>], :complete => [<Widget2>], :awaiting_approval =>[<Widget3>]}

Friday 1 June 2012

authorisation and rubyCAS

Remember, that rubyCAS only provides authentication - ie making sure that the person we're talking to belongs to the username that we've been given. It does not tell us if this user should be viewing the page we're looking at - that's up to you.

There are lots of rails authorisation (or authorization) tools out there. A good example is declarative authorization

In one of my previous projects we looked to implement centrally-hosted authorisation. Implementation ideas follow:

rubyCAS (as opposed to non-ruby CAS) happily serves up 'extra attributes' with your newly-authenticated user.

These extra attributes are usually things like name/email etc, In our case we chose to send back the user's id (from the API) and the user's type_id (which indicates if they are a partner/admin).

It should be little problem to add a 'roles' field to the api and serve this up as well.

The 'extra attributes' are available for every authentication request - so the client application will have the newest copy when a user logs in.

It's then up to the client-application to verify the freshness of the roles at appropriate points.

From then on, though, the going is easy. We can use, say, declarative_authorization perfectly naturally from then on, simply pulling the set of roles from the given field. The client-application can decide what a user can see based on the roles they are known to have.

Setting a user up with roles will be done by editing the user on the admin-application.

Now, there is a niggling limit involved that is implied by the phrase 'rubyCAS'. The extra-attributes thing works happily on rubycas-client, but may not be supported by *other* client implementations of CAS. If we wanted to add CAS-based authentication/authorisation into non-rails apps, we'd have to find a client that supported it.

Otherwise, the proof-of-concept shows that it works just fine.


This is one article in a series on Rails single-sign-on with rubyCAS

Sunday 13 May 2012

I got a Job...

Well, it's been a busy couple of weeks. I've been interviewing and code-testing and otherwise rushing back and forth like a headless chicken...

But it's all paid off, and I have myself a new job, starting Monday. I'll be working at a company in Crows Nest that specialises in software for the employment industry.

I'll be coming in at a senior level as lead developer, building one of their four main products, assisting Registered Training Organisations keep track of their students and courses.

Sunday 6 May 2012

Link: Employees and social media

This is actually a really interesting point.

13 years ago, the Cluetrain Manifesto loudly told us that we should actually (shock) listen to what our customers actually have to say - even the complaints - without trying to pretty it up for the ears of upper management. It led to companies really listening to their audience and being able to build products that addressed the real problems of their customers, rather than wasting time building solutions for some idealised pseudo-customer.

Lo and behold - the customers loved it.

Is it time we started listening to our employees the same way? Everybody has a grumble or two. But rather than everybody pretending they don't exist, and hushing them up the moment they try; perhaps it's better to create an environment of openness. One where people are not afraid to talk about the things that aren't working.

If we are prepared to really hear what somebody else has to say, even (or especially) if it's negative; then we have a chance to actually address the problem and make it a better world for all of us.

Sounds like a win-win to me.

Monday 30 April 2012

How to build a reputation in IT

There is well-known a skills-shortage for programming... but don't be fooled. There are a lot of programmers out there too. The skills shortage is about there being a lack of *good* programmers. Just rocking up with a bright new CS degree is generally not going to cut it for you. You'll just have shown up at the door along with the other thousands of new CS graduates in your city this year. So what can you do to stand out from the crowd? To prove that you are, in fact, worth being in demand? How do you build a reputation as somebody worth hiring?

There's no quick answer to this, but there is a reliable one:
It takes work.

It takes both time and effort - and the earlier you start, the better. Yes, you can (and should) start before you graduate (if possible). If you wait until afterwards, you'll be in the same pool as everybody else, hoping to be picked while you scrabble to make your resumé presentable. But if you've already been working on your reputation, then you'll be able to hit the ground running - and walk into a job as soon as you're free of university.

If you've already graduated (or you're not going through the higher-education system at all) don't worry. You can still do a lot to improve your rep - and the earlier you get started, the better you'll be.

Obviously, what you need to do will depend on your exact circumstances... so take what I say below with a grain of salt - as just one person's brainstorming session. Then figure out what you think will be good for you and just start.

Where do I start ? Should I start a blog?

Lots of places advise you start a blog... and they're kind of right. But if you're just starting out, you probably don't know exactly what to say yet. If you're just bursting with great ideas you can share (and I don't mean updates on what your sister said to you last week, or how cute your cat is), then great - go for it. A blog is a good way of showing the world you have something worth contributing... but be warned that a blog is not a get-hip-quick scheme. It generally takes about 2 years (minimum) to gain traction.

Sure, there are some notable exceptions - but they are very much the exception. Just like hundreds of attractive women coming to hollywood in the hopes of instantly becoming a star - thousands of new blogs get started in the hopes of becoming instantly famous... and most of them end up with the blog equivalent of a regular, average acting career after doing hours of work playing the dead body or acting super bouncy in hemorrhoid commercials.

So yes - start a blog if you like... but don't let that be your main focus just yet.

My best recommendation for you would be that you start out by actually coding something interesting.

Do some random side-projects and put them up on github.

Having a github account is an extremely useful recruiting tool. Much better (to the people that matter) than a plain-ole CV. You can actually show people your real code. Given that this is precisely what employers are trying to hire you for - it makes sense to have some available for them to see.

What's so interesting is just how few candidates actually bother to have any code samples at all... Most employers have to try to guess at how good a candidate really is by asking obscure technical questions - which are a second-hand guesstimation at coding ability at best. If you've got some actual code they can look at - it solves one of their biggest problems (ie whether or not the person is lying through their teeth about their programming skill). Even if your code isn't the world's best... and employer can accurately gauge your real ability... comparing that to the chance that a smooth-talker might be lying about what he/she can do, this is still a net plus.

Not sure what to work on?

Figure out something that you need yourself, or think would be cool to work on. It doesn't matter if it's been doe before - you're having a go to see how well you can do it - and show off to other people too. Yes, writing games is perfectly fine - it's how a lot of people get started, because it's fun as well as useful.

If you can't think of something yourself - have a look at the open source projects that are already out there. If you already use something (whether a tool or a game), go have a look at the code (it's free), look at the list of bugs for it (every project has one of these, though you may need to email the project owner to get a copy) and have a go at solving one of them. Then submit the code back to the project.

Another idea (if you still don't have any yet) are puzzle sites. Eg Project Euler or ruby-quiz. Work through them every week and see how far you can get. It'll tone up your problem-solving skills as well as building a back catalogue of code samples to throw at potential employers to show your mad skillz.

What about Startups?

Having a ago at a startup shows initiative and sticking power as well as all the other skills such as marketing ability. It also gives you valuable experience in the essential skill of "listening to what customers actually want"

If you have a cool idea for something you can build - try to find some like-minded friends who also want to build something, and team up. Extra people can help lessen the workload (allowing you to do more cool stuff in less time), or can flesh out areas where your expertise might be lacking (eg working back-end code if you're mostly good at front-end stuff).

Most importantly, though, is to just have a go at building something... and then shipping it!

It almost doesn't matter if you fail at a startup. You'll either have a) a product that is selling and making you money or b) some incredibly useful experience at working in a team with others and trying to get a product out to a market. As long as you aren't hocking the family home to pay for it, you can't lose.

If you don't have any like-minded friends just yet - I suggest going to hackdays and startup-weekends. A great example is launch48 - where people who want to try startups gather, and you get together to build one over the weekend. If that isn't near you, google for "(startup OR entrepreneur) internet" and your city and see what's nearby. You can also checkout the local internet entrepreneur groups in meetup.com. Finally, you could checkout MatchFounders to try and find like-minded potential-founders.

What else?

I'd also strongly recommend Stack Overflow - a question-answer help site for programming-related questions.

Solving other people's problems is a good way of showing you know your stuff. Even better is that you don't need to start with experience to help people out. There are a lot of newbies that post questions to S/O - and you may well have simply better google-fu than they do. Look through the latest-asked questions and see if you can solve any of the problems yourself by googling the answer. Then put an answer up. It doesn't matter if you're the first-answerer, as long as you get the answer right. If what you find out is helpful - you'll get voted up and will be literally building your reputation. If you get voted down - try to figure out why and do better next time. If nothing else - you'll have learned something new, and over time you'll learn the important art of effectively explaining things to others.

*Now* should I start a blog?

Only now, once you have been working on other things for a while, should you start a blog. Now, you'll have something to say...

What to blog about?

If you don't have a particular idea for your blog, I recommend you start out by blogging the solutions to problems you have in your other coding. This is a bit like Stack Overflow (and I recommend you submit your problems to both). However the approach you use on a blog is different to what you use on S/O. On S/O it's all about "here's the problem" and "here's the answer". A blog post is about the journey. How did you come across the problem? Why was it a problem for you? What did you try to solve it? How did that work out? People want to know about dead-ends too - as they want to know what to avoid if they find themselves in a similar situation. What finally worked? Who helped you? If you got help from somebody, or found a tutorial online - a linkback to them is a great way to give back.

Anything else?

So as I said - this is just my own personal brainstorming session, based on one person asking me about it... I'd love to know about other ideas for building online reputation. What worked for you? What have you heard working for other people? What did you try and backfired?

Thursday 19 April 2012

Link: The perils of opinionated software like Rails

An old guest blogpost on RailsInside caught my interest, called The perils of opinionated software like Rails. It's never a good idea to get too fanatical about one's choice of framework - so I definitely recommend having a read.


He raises some good points, including the should-be-obvious "the opposite of bad software is not necessarily good software". The specific ideas he raises are surrounding Rails' poor re-implementation of database security-checks - something that old, enterprisey-style applications leave up to the actual database, because that's been a solved problem for years. Recent versions of Rails are better at this, but I think his message is still important. We should always keep in mind that old enterprisey software may still have some good stuff that we maybe aren't using more through fear of looking enterprisey ourselves, rather than because it's actually not a good idea.

Thursday 12 April 2012

Senior RoR Dev... back on the market in Sydney

So, after a trip to Thailand, I'm finally back home in Oz and ready to look for a new role. Here's a quick overview of what I'm looking for, and what I've done - get in touch if we match up

What I'm looking for

I prefer building meaty applications solving interesting problems. I'm not interested in building cookie-cutter brochure-ware. I prefer greenfields development to maintenance work.

I like to work with agile teams - sprints and kanban is good. I do not enjoy pair-programming, so if that's your style... maybe not for me.

I prefer a relaxed and friendly culture. "enterprisey" corporations need not apply!

What have I done?

I tend to find that the "standard" recruiting tool of the Word-doc resume does not accurately reflect my skills, so here's a list of my work and my presence online in the technical sphere. Go have a look for yourself.

LinkedIn has the closest thing to a resume. This is my profile page on LinkedIn

You're currently *looking* at my technical blog - showing my howtos and code snippets etc

I have a WorkingWithRails profile.

I have a StackOverflow profile.

I have a github account.
There's no recent work in github as I've been traveling a lot this past year, but you can see the patches I submitted to rails core (for Rails 3) - which centred around my work on the HyperActive Resource gem, which I was converting to the core Active Resource code.

I led a team building a startup website (called Matchfounders) back in Sep 2010 over a hackday weekend (called Launch48).
After the weekend, I took the prototype (in PHP) and rewrote it in Rails 3 (adding such trivialities as a test suite and actual security measures)... then developed it a *little* bit more. It's not currently under development but go have a look to see what I can do in about a week's worth of work.

Not immediately evident from the above, but I was active in the RoR oceania community in Sydney before I left Sydney, as well as SLUG - where I gave a howto talk on Rails about four years ago.

When I went to London I was active in LRUG (the London Ruby Users Group), also giving a couple of talks, one of which is online here: Rubyprof and kcachegrind

I briefly featured on a peepcode podcast, interviewed by Geoffrey Grosenbach about my work on HyperActive Resource... but I'll admit I was somewhat overawed and didn't come off sounding particularly clever.

Last and most definitely least I have a website... but it is the neglected poor cousin of all my other sites and is not worth looking at
(*cough* not updated since I left Sydney three years ago *cough*)

Conclusion

I'm an experienced senior Ruby Developer in Sydney - looking for a position in a solid company doing cool things. Drop me an email at this email address

Tuesday 27 March 2012

Link: What is turning women off coding?

Following from are women in tech really in tech we have:

Some things to think about before you exhort everyone to code by Miriam Posner

Which points out the important cultural aspect of why it is that women are often not coders.

If you are not a woman in tech, and wonder why there are so few... this article is for you.

So is this recent article on the recent "brogramming" phenomenon: Brogramming: just one of the girls by addabirnir from Skillcrush

She points out that "brogramming" has its intentions in the right place: it is just trying to inject some appeal into coding... but is doing so in a blatantly misogynistic fashion. (eg "without brogramming, bros might just feel like...one of the girls") and thereby alienating the very few women who are trying to break into this industry.

The important take-home message from her is "you don’t need to alienate anyone to make yourself comfortable"

Also of very distinct interest is the NYT article about Wikipedia's serious gender imbalance, which also points the finger strongly at geek culture - which is extremely male, and can be very uncomfortable for a woman.

Speaking personally on this subject, it took me a good ten years before I figured out the rules for getting along in geek society. My feminine upbringing was with an entirely different, incompatible culture. I can well understand that the serious culture shock would be offputting to the point where many women might not even want to bother continuing.

Again, I'd recommend reading all these article to get a glimpse into why this is the case.

Thursday 22 March 2012

Performance review vs company policy

A post inspired by 1.00 FTE:

Makes the obvious point - any truly bad behaviour should be addressed specifically with the given person. Otherwise you end up with gargantuan employee policy documents filled with items best left to local law enforcement.

The question then becomes, where to draw the line? I also think we can apply this principle to the grey-areas - the smaller infractions that, if policies are created, become annoyances that the rest of the staff must deal with.

I've been here before... company-wide policies on email, facebook, draconian time-clocking... generally only instigated when some young intern has done something stupid, so everybody else has to suffer for his/her bad behaviour.

Sure, if somebody abuses your trust then punish them, or fire them, or put them on probation or whatever you need to do. but changing a policy for the entire company is overkill. Especially when it degrades the previously open and enjoyable culture that you spent so many years developing.

Don't let the actions of a single individual degrade the trust that you give to your other employees. Trust is hard-won and easily lost, for sure... but it's also an essential component of a happy workplace. People don't want to be treated like they are children - and will find it stressful to be constantly nannied when they are capable of looking after themselves.


With a nod to the fact that some people *do* need supervision, try to trust your employees to at least act like the adults they are. After all - people try to meet your expectations... whatever they are.

Saturday 17 March 2012

Do I look fat in this picture?

Blogger is doing a most unkind thing with profile pics - it scales to fit and does not respect the aspect ratio.

I've updated my profile pic to match the "acceptable" ratio on the full-size profile page (FYI everything is scaled to 140px wide and 180px tall). Previously it was stretching it width-ways and making me look like the fat-mirror in the hall of mirrors. :P

Of course my profile pic is a few years old now... but still close enough to life for people to recognise me, and I'd like it to stay that way.

Tuesday 13 March 2012

Go the fuck home...

Jeff Atwood (of CodingHorror) recently left StackExchange after four years of really hard work. He gave his reasons in a farewell to StackExchange - explaining that he has realised that, as amazing as it is to work on a brilliant project... it's not worth missing out on your children.

To this I'll add a recent Ignite talk: Go the fuck home by Pam Selle

I totally agree.

Anything over a 40 hour week is really stupid. Not just for you, but also for the business you're working for. Many good books have pointed out that, not only do you not do your best work after five... but sometimes you can be actively sliding backwards (making more bugs that have to be cleaned up).

Of course the business won't say no. They think they're getting extra work from you for free... But remember that old deathbed adage about nobody feeling like they should have spent more time at the office.

Don't ever forget that any extra time at work is at the expense of your most precious commodity - your own life.

You only have one, and it's shorter than you think.

Get Real about how you're spending it.

You really don't win anything by giving it away for free to an employer that *maybe* might pat you on the back and give you a tiny pay-bump when your next review comes around.

yes, some companies are amazing, wonderful places to work for and you truly enjoy being there, that's great.... but this is the exception, not the rule, and even so - think about Jeff Atwood. StackExchange really is one of the really amazing places... but it still isn't Your Life (the only one you've got). So really think, then think again about your priorities here.

I know what it's like. Your boss tells you that it's critical to hit the next deadline and all but orders you to pull an allnighter? You do know they actually cant enforce that don't you?

Afraid you might lose your job? yes, you might... and then you might go find one where they treat you like a human, instead of a "business resource" to be pushed around at will.

Again, unless you're in a rare position, you probably aren't building the cure for cancer... and that deadline, while it might hit the company's bottom line today, probably won't cause people to actually die if you miss it... but what will happen is that you will continue to prop up a company that has very poor planning skills - and that is willing to exploit its workers at the expense of their time, health and sanity... and you're helping them do it?

Go the fuck home!

Tuesday 6 March 2012

Link: Finding offshore ruby vendors that don't suck

Finding good "help" is always tough. When your help is located thousands of miles away in a country where english is a second language... that can be even tougher. How exactly do you filter out the dross and find the diamonds?

C42 have just put up a really interesting tutorial on how to identify offshore ruby on rails vendors that don't suck. I've never outsourced myself, but this looks like it would be a good starting point.

Wednesday 29 February 2012

Are "Women in tech" really in tech?

Anneke Jong has posted an interesting article called why we need to rethink women in tech, which points out the real reason for the seeming disparity in numbers of "women in tech" comes about due to the definition of "in tech" being used.

She explains that while several recent articles are applauding the increase of "women in tech" - these numbers are gathered from women who are, in essence, working in tech-adjacent roles (eg marketing and PR for IT firms, or tech-bloggers such as herself), rather than actually having coding skills - which would be the definition of "technical" for those working in the industry.

As a coder-girl myself, I can see her point. There has indeed been a great uptake of "women in tech"... but the increase of actually technically-competent women is much slower.

While the figures quoted in media seem good at first glance - they aren't telling the full story of the gender imbalance. Anneke makes a great comparison with the music industry: "Imagine your disappointment if only a third of the 'Top Women in Music' were musicians."

This is not to say there has been no progress over the last twenty years. When I began my Comp Sci degree, I was one of only seven women in a class of 220, which was no uncommon at the time - whereas now the proportion is closer to 1 in 10... but that is still a far cry from 50%

The article, of course, offers no solutions - because generating interest for computing (or maths, for that matter) in women is still one of the Hard Problems facing education... but it's a good discussion of the problem, and worth a read.

Friday 24 February 2012

I'm on AllTop for ruby

I made it to the AllTop ruby feed.

Apparently this is a big deal? They even have badges (see my ever-growing pile of badges at the bottom of my left-nav).

All part of my recent bout of SEO link-building experimentation in the last few weeks.

Saturday 18 February 2012

Industry-average productivity?

An interesting point here that is quite true. Effort isn't enough... however - is it really possible to compare groups of IT guys against "industry average"? What data do we have on "industry average"?

Have we gathered reliable data on any of these? How would be go about collecting it and is it even really possible to do that reliably?

I guess it's possible if you're doing work that's already been done (eg building a better mousetrap)... maybe if you're churning out cookie-cutter brochure-ware websites perhaps? Or Yet Another Spreadsheet App?

Even so - I'd be curious how you'd determine the productivity of other groups in your industry - what is it exactly that we're averaging? Time to complete features? Code quality? Lines Of Code? :|

Even if we decide on a metric, asking people in your own company about their past experiences will only give you a few datapoints - possibly distorted by 20/20 hindsight (or whether you want to come off looking better than reality might show up). I don't know of any reliable info out there apart from this kind of self-gathered stuff.

How do we go about gathering data across companies and how do we trust that data? It'd still be self-reported and therefore open to various forms of bias ("Yeah, my *old* team used to be awesome! nothing like this group of idiots!"), differing levels of slave-driving ("Yes, *my* team got it done in a week... just ignore the shackles on their legs!"), differing levels of quality ("we got it done over a weekend! security? testing? what's that?") and downright manipulation ("yeah, we're Team Awesome and can code up a custom-built website in only 24hours!!!!")

Not that it wouldn't be worth giving it a go.. but of course you still fall back on the problem of metrics. What metrics reliably indicate productivity (especially when we need to hold code quality constant)?

"Features" produced per week perhaps? but what is a "feature"? how big is it? how do we compare across companies and even across industries? It's a tough call - made even harder when you add the "quality" constraint. Is a cavalier team churning out unplanned, untested code full of security holes *more* productive than a careful one that designs something elegant and simple, robust and well-tested?

Measuring quality is always a tough nut to crack.

I've seen people try for "customer satisfaction" - but in our industry, it also pays to ask "which customer?" - the one paying the bill or the one that is forced to actually use the product? Another example of Who is the real user here?

So... are there any resources out there? and what's people's experiences of their quality?

Sunday 12 February 2012

Link: Who should learn to code

Who should learn to program presents a brief look at the reasons why everyone should learn to program, and also a very good reason why not. Worth a look.

Monday 6 February 2012

Estimates and hiking

A fairly standard question on quora: Why are software development task estimations regularly off by a factor of 2-3? has sparked some discussion.

The best answer given was an extremely entertaining hiking analogy (it's the top-voted answer - go see), explaining the software development process in terms of the fractal-nature of a coastline, with unexpected delays along the way.

I think it's a great analogy as it goes and would be extremely helpful in getting the idea of unexpected scope-creep across to a complete IT-newbie.

The answer then spawned a plethora of comments and even a counter-post that is also really interesting: Why Software Development Estimations Are Regularly Off, which explains that the hiking analogy is way off, and that software estimation is more like inventing.

I agree... though I still see great value in the hiking analogy for explaining "what goes wrong" on the kind of project that encounters the problems described.

The counter-post has itself sparked a discussion on Y-combinator which goes into a lot more detail about estimation issues in general.

It's all provided me with an entertaining read on an otherwise well-picked-over subject.

Tuesday 31 January 2012

Link: Rough Estimation Oath

OMG how much do I love this oath!!!

I might put it in my standard contract going forward :)

Wednesday 25 January 2012

Project Euler Upgrade

Just a quick post as a follow-on to my project Euler post a while back.

Project Euler have had a site revamp. A bit of a nicer UI prettier progress-tracking and addition of merit-badges to mark some interesting milestones along the way.

The fun is still in solving mind-twisting math-puzzles... but it's at least nicer to look at now ;)

Thursday 19 January 2012

Link: The hungry programmer

The hungry programmer compares healthy eating to healthy code-practices, discussing the code-quality equivalent of the "healthy eating continuum". In brief:

If you take the McDonald's approach and ship shit then you satisfy that need in the short-term. But you'll feel the effects in the long-term. Your code will be harder to maintain and need more attention later. It won't have a long and healthy life.

I know there have been several times when we just *had* to ship *something*... no matter the guilt I felt at the poor quality that was going out the door. I much prefer to spend some time *now* and work at the better-quality result - even if it means "going hungry" for just that little bit longer. Still, I also understand that a business has to ship to remain a viable business... It's one of those universal dilemmas.

What experiences have you had? Any spectacularly difficult trade-offs you had to make?

Friday 13 January 2012

Link: link-building and SEO

It's fairly old, but this is still a good basic reference to SEO and link-building

Just be aware that IPL2 is no longer accepting link submissions. You have to register as an editor for joeant to be able to submit to them (which is free, and you don't have to submit any other links, though it helps).

This one also has some good ideas: How to build links fast
...and some hilariously dumb ones at the end (including "sue google" and the RIAA technique). :)

Anybody have any more recent good tutorials on link-building?

Saturday 7 January 2012

Everybody thinks they're above average...

A post inspired by 1.00 FTE:

This is a bit of an aha moment - I'd especially recommend reading the comments about what happens when the perceived capabilities clash.

I have left a job where my perceived capability was well below what I later found out to be reality. I definitely experienced a chafing-at-the-bit (or perhaps "crushed-beneath-the-boot") sensation at that workplace. I was constantly irritated that the mid-level manager didn't seem to trust me to do my job.... even when I tried valiantly to prove my capability, eventually bringing about a revolution to their help-desk system for which I still occasionally receive praise (six years after I've left).

Perhaps the manager was right - perhaps I wasn't as good as I thought I was... but given that I literally doubled my income when I walked out the door (and haven't looked back since), I doubt it.

I recognise it's difficult for non-IT-front-line bosses to accurately gauge the skill of their techies (see my old article on The economics of IT salaries for a discussion) but it's still not good when this sort of thing happens.
That being said - there is absolutely a real need to provide direction for those that need it, and to make sure that everybody's on the same page. So... what to do?

Is it better to downgrade everybody's skill level to make sure nobody incompetent accidentally gets through and influences strategy until they've "proven" they are capable? Or is it better to trust first?

I'd go for the latter... mainly because I agree with the old adage of "people will meet your expectations whatever they are"... but then I don't have to pay the bills. Opinions?