Serializing (And Deserializing) Objects With Ruby

Serialization is one of those things you can easily do without until all of a sudden you really need it one day. That’s pretty much how it went with me. I was happily using and learning Ruby for months before I ever ran into a situation where serializing a few objects really would have made my life easier. Even then I avoided looking into it, you can very easily convert the important data from an object into a string and write that out to a file. Then when you need to, you just read the file, parse the string and recreate the object, what could be simpler? Of course, it could be much simpler indeed, especially when you’re dealing with a deep hierarchy of objects. I think being weaned on languages like Java, you come to expect operations like serialization to be non-trivial. Don’t get me wrong, it is not really difficult in Java, but neither is it simple and if you want your serialized object to be human-readable, then you’re into 3rd party library land and things can get easier or harder depending on your needs. Suffice to say, bad experiences in the past don’t fill you with a lot of enthusiasm for the future.

When I started looking into serialization in Ruby, I fully expected to have to look into 3rd party solutions – surely the serialization mechanisms built into the language couldn’t possibly, easily fit my needs. As usual, I was pleasantly surprised. Now, like that proverbial hammer, serialization seems to be useful all the time :). Anyway, I’ll let you judge for yourself, let’s take a look at the best and most common options you have, when it comes to serialization with Ruby.

Human-Readable Objects

Text

Ruby has two object serialization mechanisms built right into the language. One is used to serialize into a human readable format, the other into a binary format. I will look into the binary one shortly, but for now let’s focus on human readable. Any object you create in Ruby can be serialized into YAML format, with pretty much no effort needed on your part. Let’s make some objects:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
require "yaml"

class A
  def initialize(string, number)
    @string = string
    @number = number
  end

  def to_s
    "In A:\n   #{@string}, #{@number}\n"
  end
end

class B
  def initialize(number, a_object)
    @number = number
    @a_object = a_object
  end

  def to_s
    "In B: #{@number} \n  #{@a_object.to_s}\n"
  end
end

class C
  def initialize(b_object, a_object)
    @b_object = b_object
    @a_object = a_object
  end

  def to_s
    "In C:\n #{@a_object} #{@b_object}\n"
  end
end

a = A.new("hello world", 5)
b = B.new(7, a)
c = C.new(b, a)

puts c```

Since we created a to_s, method, we can see the string representation of our object tree:

<pre>In C:
 In A:
   hello world, 5
 In B: 7
  In A:
   hello world, 5</pre>

To serialize our object tree we simply do the following:

```ruby
serialized_object = YAML::dump(c)
puts serialized_object```

Our serialized object looks like this:

<pre>--- !ruby/object:C
a_object: &id001 !ruby/object:A
  number: 5
  string: hello world
b_object: !ruby/object:B
  a_object: *id001
  number: 7</pre>

If we now want to get it back:

```ruby
puts YAML::load(serialized_object)```

This produces output which is exactly the same as what we had above, which means our object tree was reproduced correctly:

<pre>In C:
 In A:
   hello world, 5
 In B: 7
  In A:
   hello world, 5</pre>

Of course **you almost never want to serialize just one object**, it is usually an array or a hash. In this case you have two options, either you serialize the whole array/hash in one go, or you serialize each value separately. The rule here is simple, if you always need to work with the whole set of data and never parts of it, just write out the whole array/hash, otherwise, iterate over it and write out each object. The reason you do this is almost always to share the data with someone else.

If you just write out the whole array/hash in one fell swoop then it is as simple as what we did above. When you do it one object at a time, it is a little more complicated, since we don't want to write it out to a whole bunch of files, but rather all of them to one file. It is a little more complicated since you want to be able to easily read your objects back in again which can be tricky as <span style="font-style: italic;"></span>_YAML_ serialization creates multiple lines per object. Here is a trick you can use, when you write the objects out, separate them with two newlines e.g.:

```ruby
File.open("/home/alan/tmp/blah.yaml", "w") do |file|
  (1..10).each do |index|
    file.puts YAML::dump(A.new("hello world", index))
    file.puts ""
  end
end```

The file will look like this:

<pre>--- !ruby/object:A
number: 1
string: hello world

--- !ruby/object:A
number: 2
string: hello world

...</pre>

Then when you want to read all the objects back, simply set the input record separator to be two newlines e.g.:

```ruby
array = []
$/="\n\n"
File.open("/home/alan/tmp/blah.yaml", "r").each do |object|
  array &lt;&lt; YAML::load(object)
end

puts array```

The output is:

<pre>In A:
   hello world, 1
In A:
   hello world, 2
In A:
   hello world, 3
...</pre>

Which is exactly what we expect &#8211; handy. By the way, I will be covering things like the input record separator in an upcoming series of posts I am planning to do about Ruby one-liners, so don't forget to subscribe if you don't want to miss it.

## A 3rd Party Alternative

Of course, if we don't want to resort to tricks like that, but still keep our serialized objects human-readable, we have another alternative which is basically as common as the Ruby built in serialization methods &#8211; <a href="http://www.json.org/" target="_blank">JSON</a>. The JSON support in Ruby is <a href="http://flori.github.com/json/" target="_blank">provided by a 3rd party library</a>, all you need to do is:

<pre>gem install json</pre>

or

<pre>gem install json-pure</pre>

The second one is if you want a pure Ruby implementation (_no native extensions_).

**The good thing about JSON, is the fact that it is even more human readable than YAML**. It is also a "_low-fat_" alternative to XML and can be used to transport data over the wire by AJAX calls that require data from the server (_that's the simple one sentence explanation :)_). The other good news when it comes to serializing objects to JSON using Ruby is that if you save the object to a file, it saves it on one line, so we don't have to resort to tricks when saving multiple objects and reading them back again.&nbsp;

There is bad news of course, in that your objects won't automagically be converted to JSON, unless all you're using is hashes, arrays and primitives. You need to do a little bit of work to make sure your custom object is serializable. Let&rsquo;s make one of the classes we introduced previously serializable using JSON.

```ruby
require "json"

class A
  def initialize(string, number)
    @string = string
    @number = number
  end

  def to_s
    "In A:\n   #{@string}, #{@number}\n"
  end

  def to_json(*a)
    {
      "json_class"   =&gt; self.class.name,
      "data"         =&gt; {"string" =&gt; @string, "number" =&gt; @number }
    }.to_json(*a)
  end

  def self.json_create(o)
    new(o["data"]["string"], o["data"]["number"])
  end
end```

Make sure to not forget to '_require_' json, otherwise you'll get funny behaviour. Now you can simply do the following:

```ruby
a = A.new("hello world", 5)
json_string = a.to_json
puts json_string
puts JSON.parse(json_string)```

Which produces output like this:

<pre>{"json_class":"A","data":{"string":"hello world","number":5}}
In A:
   hello world, 5</pre>

The first string is our serialized JSON string, and the second is the result of outputting our deserialized object, which gives the output that we expect.

As you can see, we implement two methods:

  * _**to_json**_ &#8211; called on the object instance and allows us to convert an object into a JSON string.
  * _**json_create**_ &#8211; allows us to call _JSON.parse_ passing in a JSON string which will convert the string into an instance of our object

You can also see that, when converting our object into a JSON string we need to make sure, that we end up with a hash and that contains the '_json_class_' key. We also need to make sure that we only use hashes, arrays, primitives (_i.e. integers, floats etc., not really primitives in Ruby but you get the picture_) and strings.

So, JSON has some advantages and some disadvantages. I like it because it is widely supported so you can send data around and have it be recognised by other apps. I don't like it because you need to do work to make sure your objects are easily serializable, so if you don't need to send your data anywhere but simply want to share it locally, it is a bit of a pain.

## Binary Serialization

<p style="text-align: center;">
  <img align="middle" alt="Binary" class="aligncenter size-full wp-image-1696" height="196" src="http://www.skorks.com/wp-content/uploads/2010/04/binary.jpg" style="width: 295px; height: 196px;" title="Binary" vspace="3" width="295" srcset="https://www.skorks.com/wp-content/uploads/2010/04/binary.jpg 500w, https://www.skorks.com/wp-content/uploads/2010/04/binary-300x199.jpg 300w" sizes="(max-width: 295px) 100vw, 295px" />
</p>

The other serialization mechanism built into Ruby is binary serialization using <a href="http://ruby-doc.org/core/classes/Marshal.html" target="_blank"><em>Marshal</em></a>. **It is very similar to _YAML_ and just as easy to use, the only difference is it's not human readable as it stores your objects in a binary format**. You use Marshal exactly the same way you use YAML, but replace the word YAML with Marshal :)

```ruby
a = A.new("hello world", 5)
puts a
serialized_object = Marshal::dump(a)
puts Marshal::load(serialized_object)
In A:
   hello world, 5
In A:
   hello world, 5

As you can see, according to the output the objects before and after serialization are the same. You don’t even need to require anything :). The thing to watch out for when outputting multiple Marshalled objects to the same file, is the record separator. Since you’re writing binary data, it is not inconceivable that you may end up with a newline somewhere in a record accidentally, which will stuff everything up when you try to read the objects back in. So two rules of thumb to remember are:

  • don’t use puts when outputting Marshalled objects to a file (use print instead), this way you avoid the extraneous newline from the puts
  • use a record separator other than newline, you can make anything unlikely up (if you scroll down a bit you will see that I used ‘——’ as a separator_)

The disadvantage of Marshal is the fact the its output it not human-readable. The advantage is its speed.

Which One To Choose?

It’s simple, if you need to be able to read your serializable data then you have to go with one of the human-readable formats (YAML or JSON). I’d go with YAML purely because you don’t need to do any work to get your custom objects to serialize properly, and the fact that it serializes each object as a multiline string is not such a big deal (as I showed above). The only times I would go with JSON (aside the whole wide support and sending it over the wire deal), is if you need to be able to easily edit your data by hand, or when you need human-readable data and you have a lot of data to deal with (_see benchmarks below_).

If you don’t really need to be able to read your data, then always go with Marshal, especially if you have a lot of data.

Here is a situation I commonly have to deal with. I have a CSV file, or some other kind of data file, I want to read it, parse it and create an object per row or at least a hash per row, to make the data easier to deal with. What I like to do is read this CSV file, create my object and serialize them to a file at the same time using Marshal. This way I can operate on the whole data set or parts of the data set, by simply reading the serialized objects in, and it is orders of magnitude faster than reading the CSV file again. Let’s do some benchmarks. I will create 500000 objects (a relatively small set of data) and serialize them all to a file using all three methods.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
require "benchmark"

def benchmark_serialize(output_file)
  Benchmark.realtime do
    File.open(output_file, "w") do |file|
      (1..500000).each do |index|
        yield(file, A.new("hello world", index))
      end
    end
  end
end

puts "YAML:"
time = benchmark_serialize("/home/alan/tmp/yaml.dat") do |file, object|
  file.puts YAML::dump(object)
  file.puts ""
end
puts "Time: #{time} sec"

puts "JSON:"
time = benchmark_serialize("/home/alan/tmp/json.dat") do |file, object|
  file.puts object.to_json
end
puts "Time: #{time} sec"

puts "Marshal:"
time = benchmark_serialize("/home/alan/tmp/marshal.dat") do |file, object|
  file.print Marshal::dump(object)
  file.print "---_---"
end
puts "Time: #{time} sec"
YAML:
Time: 45.9780583381653 sec
JSON:
Time: 5.44697618484497 sec
Marshal:
Time: 2.77714705467224 sec

What about deserializing all the objects:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
def benchmark_deserialize(input_file, array, input_separator)
  $/=input_separator
  Benchmark.realtime do
    File.open(input_file, "r").each do |object|
      array &lt;&lt; yield(object)
    end
  end
end

array1 = []
puts "YAML:"
time = benchmark_deserialize("/home/alan/tmp/yaml.dat", array1, "\n\n") do |object|
  YAML::load(object)
end
puts "Array size: #{array1.length}"
puts "Time: #{time} sec"

array2 = []
puts "JSON:"
time = benchmark_deserialize("/home/alan/tmp/json.dat", array2, "\n") do |object|
  JSON.parse(object)
end
puts "Array size: #{array2.length}"
puts "Time: #{time} sec"

array3 = []
puts "Marshal:"
time = benchmark_deserialize("/home/alan/tmp/marshal.dat", array3, "---_---") do |object|
  Marshal::load(object.chomp)
end
puts "Array size: #{array3.length}"
puts "Time: #{time} sec"
YAML:
Array size: 500000
Time: 19.4334170818329 sec
JSON:
Array size: 500000
Time: 18.5326402187347 sec
Marshal:
Array size: 500000
Time: 14.6655268669128 sec

As you can see, it is significantly faster to serialize objects when you’re using Marshal, although JSON is only about 2 times slower. YAML gets left in the dust. When deserializing, the differences are not as apparent, although Marshal is still the clear winner. The more data you have to deal with the more telling these results will be. So, for pure speed – choose Marshal. For speed and human readability – choose JSON (at the expense of having to add methods to custom objects). For human readability with relatively small sets of data – go with YAML.

That’s pretty much all you need to know, but it is not all I have to say on serialization. One of the more interesting (and cool) features of Ruby is how useful blocks can be in many situations, so you will inevitably, eventually run into a situation where you may want to serialize a block and this is where you will find trouble! We will deal with block serialization issues and what (if anything) you can do about it in a subsequent post. More Ruby soon :).

Images by Andrew Mason and just.Luc

Why Aren’t You Awesome Yet? (Learning Via The World-Wide Community)

This is the fifth post in the teaching and learning series. The teaching and learning series includes the following posts:

  1. All Developers Should Know How They Learn Best
  2. The Secret Of Being A Great Mentor
  3. The Secret Of Being A Great Apprentice
  4. Become A Better Developer By Indexing Your Brain
  5. Why Aren’t You Awesome Yet? (Learning Via The World-Wide Community)
  6. What Playing Cards Can Teach Us About How We Learn – And How Fast We Do It

These days there are unprecedented opportunities for you to learn, improve yourself and your skills. We often tend to take it for granted that information is at our fingertips and yet, at the same time, it has become so ubiquitous that we sometimes don’t even realize that the answers to our questions are right there to be found. We fall back to the tried and true method of asking the people around us, perhaps we might even remember to do a quick Google search, but if that doesn’t bear immediate fruit, we sit back, scratch our head and hope that the information we want/need will somehow appear. But, it doesn’t have to be this way.

Books

You know, people don’t seem to have enough respect for books and developers are as guilty as most. I am not sure if this is a product of our age or if it has always been this way. I can’t tell you how many times people have argued with me, staunchly defending the position that books are useless (I keep meaning to write a post about this, I still might). You see, apparently, the only way to learn is by doing and so books are a waste of time. There are so many things wrong with that statement, but I might save all of them for that other post, in case I ever get around to writing it. Let me just say this, doing it” is the only way to PRACTICE, as far as learning goes, there are lots of different ways, with books sitting right up there at number one (or at least the top three). I don’t want to go on a tangential rant here, but you can probably tell that I love books :) and believe that you can never read too many – (_I am not the only one_).

The good news is that book availability is at an all-time high. Take a step back and just consider what a service like Amazon provides for the book lover. All the books you ever wanted are only a click away. Robust search capabilities make sure you can find the most popular/most relevant books for your topic of interest. Reviews by other people, with similar interest, help you separate the mediocre books from the awesome ones; recommendations give you a trail to follow for further study. And then there are services like Booko (only for Australia though :)) to make sure you get the most for your hard-earned dollar. Contrast this with how it used to be, as recently as 10-15 years ago. The only places to get books were bookshops and libraries, this is fine, but the problem is limited selection, not to mention the difficulty of finding out about the “best” books in the first place. If your area of interest was specialised, you would have to be part of the community around this topic (e.g. be studying for a degree in that particular area) to even learn of the existence of some of these books. And when you did learn, the recommendations you get would be limited to several people at most. That’s the difference between a world-wide community working on your behalf vs. a local one (or none at all).

Of course books are not the only way to learn, you can learn much by interacting with the experts. Except experts are busy people and hard to get a hold of, right? Maybe a few years ago this would have been true; the only way to get exposure to an expert in your field would have been to go to them (e.g. conferences) or for them to come to you (hired by your company). These ways are still valid (no matter how infrequent/unlikely), but this day and age, every expert and his pet has at least some kind of presence online. Many have blogs where you can be exposed to their thoughts, sometimes on a daily basis. Admittedly it may be hard to find the truly useful blogs, but it is eminently possible especially considering that the world-wide community is also working on your behalf in this instance (more on this shortly). Blogs you say, blogs are old-school, Twitter is the new black! I am exaggerating, they both have their place, but Twitter does often allow you to make instant connections with people you want to reach. When me and my friend @mat_kelcey were having trouble with RSpec and twitted our woes to the world, it only took a couple of hours before David Chelimsky came to our rescue – and he wrote RSpec! It doesn’t really boggle your mind any more, we’re all kinda used to it – still it’s freaking awesome :).

If you think that seeking out experts in your field to learn from them is for the birds, why not get the experts to seek you out? Start a blog of your own. I guarantee that if the stuff you write is interesting and compelling enough, people will come to have a look, start a conversation and some of these will be the very experts you wanted to reach. I don’t have to go further than my own blog for an example. I am by no means a guru, I simply try to write about what I learn, express my opinions and make it all reasonably interesting. But, you write enough about particular topics, and people in the relevant communities take notice. For example, I have written a bit about Ruby, and I’ve had people who are deeply involved in the Ruby community come and comment on my posts (_I’ve even had David Heinemeier Hansson come and correct my grammar for me :)_). I’ve expressed strong opinions quoting people well-known in our industry, only to have these people come along and pull me up on what I said, teaching me some valuable lessons as a result.  I’d be lying if I said I didn’t derive at least some satisfaction from knowing I have not only reached the people who can learn something from my posts, but also reached the ones who can expand on what I say, offer an authoritative opinion and teach both me and everyone else something as a result. There is nothing stopping you from doing the same. Infact, it would be great if you did, it can only benefit the community in the long run.

Learning

Talking about the world-wide community, there are quite a few prominent places which foster this in our field. Stack Overflow comes to mind as the most recent one, Reddit (_proggit more specifically_) and Hacker News have been around for a while. All these sites have different goals and do things differently from each other, but all of them build a community of like-minded individuals around them. These are the places where you can meet and interact with people who are just like you, from novices to experts. You can receive help and help someone else out. You no longer have to sit there scratching your head, you can get any question answered, you just need to ask. And if you want to understand what you know better, why not answer some questions yourself. And remember how I said that finding relevant resources online may be hard, well not any more, the community has done all the work for you, all you have to do is consume. But of course if you produce as well, you improve the ecosystem all-round and make the community stronger as a result. This benefits everyone, including you, everyone learns something, everyone improves.

I can’t go past the greatest community collaboration effort of all – Wikipedia. I recently spoke about the need for developers to revive and maintain their math skills. Steve Yegge proposed that one way of doing this is to simply surf Wikipedia. Pick a math topic that interests you, read about it on Wikipedia and just follow the links until you get sick of it. Keep doing this for a while and you will be amazed at how much math you will pick up. But of course, this doesn’t just apply to math, pick any broad topic that interests you and do the exact same thing. You may not get the most in-depth treatment, but you will get an intro and plenty of pointers to more information. The best thing is, unlike a normal encyclopaedia, it almost never goes out of date. It is actually even better than that. When Tim Bray announced that he was joining Google on his blog, I found out about it within I few hours (from Reddit or Hacker News I believe, see what I mean about community :)). As I was reading his blog post, I decided to go to Wikipedia to refresh my memory on exactly what he has done with his life. Do you know what the first thing that grabbed my attention was?

“…Tim was the Director of Web Technologies at Sun Microsystems until his resignation on February 26th, 2010. On March 15th, 2010, he announced on his blog that he’d taken up a position as a Developer Advocate at Google, focusing on Android…“

Did you catch that? It was on Wikipedia almost before Tim himself announced it. It certainly made me widen my eyes for a second, especially considering that only a few hundred years ago, you would have been lucky to get information sometimes decades out-of-date if you got it at all (_read Bill Bryson’s A Short History Of Nearly Everything, it is a great book in general but will also give you an appreciation for how slow information spread in years gone by, so slow that it was often independently invented by multiple people decades apart_). Really puts things in perspective.

Wikipedia

If all of this wasn’t enough to energize you and help you become the best that you can possibly be, there is the Open Source movement. Open Source has really come into its own over the last decade. No matter what you want to do these days, there are Open Source tools and libraries available to you, that are just as good – or better – than any commercial offering, and the community (all the things I talked about above) can help you find the best tools for your needs. You not only have the resources to learn anything you want, you also have the resources to DO anything you want. That is to say, if you want to practice (remember what I said about practice), there is nothing in your way. And Open Source doesn’t just mean free, it means OPEN SOURCE! You can study the code, change it, see how everything is put together. You can pick up style and techniques that you will not be able to find in any book. This is know-how right from the trenches and all you need to spend is a little bit of your time.

At no other time in the history of the world, have we had access to so much information, on any topic you may find of interest. At no other time, have we had tools at our disposal to organise it all and find just the right resources to give us the best “_bang for our buc_k”, when it comes to both finances and time expenditure. It is easier than ever to become a world-class expert on anything you want without even having to get a formal education in the subject. It is easier than ever to be awesome at what you do! So I will ask you once again, why aren’t you awesome yet?

_Well, we’re in the home-stretch now, the teaching and learning series is almost complete, only one post left – don’t miss it – should be the most interesting one yet_.

Images by gaspi *your guide, dkuropatwa and quartermane

How The Quest For Efficiency Turns Small Problems Into Big Ones

PrioritizeWhen Sun released Java 1.5 (or Java 5, as they rebranded it) many people were eager to upgrade their projects to use this latest and greatest version. And why not, it offered some compelling features (arguably), the most visible of which was generics support. The project I was working on was no exception. Of course, in the enterprise world this upgrade path took a while (as enterprise things are wont to do :)), but eventually all obstacles were removed and the upgrade happened. But, along with all the “goodness”, came the several thousand warnings telling you exactly how generics non-compliant your code was. There is nothing inherently wrong with this; it is good to know when there are issues with your code, even if these issues are relatively minor. The problem was that these warnings became a permanent fixture. You see, we do software development the efficient way these days, we prioritize everything and fixing trivial warnings, that don’t actually affect the functionality, never had a chance of being prioritized anywhere except the bottom.

Initially I had no problem with this, I am as efficient as the next guy, and I believe in prioritization, but after a while something just started to bug me about the code (no pun intended :)). It just didn’t look clean somehow and no amount of refactoring seemed to help. Plus, we just didn’t seem to be as thorough – or maybe it was all my imagination. An insight into this issue didn’t hit me until long after I was no longer on that project. You see it was all about those generics warnings! By upgrading and introducing several thousand new warnings into the code we turned our code into the ultimate house with broken windows (or at least cracked ones). And due to our well intentioned prioritization efforts, we never really had any intention of fixing this issue. You can probably guess how the story goes from here. Soon, a couple of legitimate warnings crept into the list, and before we knew it the couple turned into ten which quickly turned into several dozen. And you do try to fix the legitimate ones, but the psychological effect of staring into several thousand warnings will not be denied. Eventually you develop warning blindness (_similar to ad blindness_) and it doesn’t matter if the warnings are legitimate or frivolous, you no longer bother, you just treat them as noise.

Prioritization And Timeboxing

Prioritize

Prioritization seems like one of those practices that brings nothing but good. It’s pretty exciting because it is so easy to do and it has immediate benefits (_kinda like standup meetings_). We just move our features/tasks around, chop the least important ones off the bottom and all of a sudden we’re making our deadlines, we’re delivery focused. But, no practice is applicable universally. I am not trying to say that prioritization is bad; it is often a valuable and helpful practice as long as we don’t apply it blindly. There will be situations where it will make sense to prioritize a less important task/feature higher, for reasons other than its relative business value. Like the thousand warnings problem. Even a minor daily/weekly effort to fix the issue would have kept it at the forefront and prevented a tiny problem from escalating in unexpected ways.

Maybe letting a few warnings slide is not such a big deal but the underlying issue of universally applying a seemingly benign practice can manifest itself in a more insidious fashion. Let’s consider timeboxing, another one of those practices that brings nothing but good. If we timebox, we’re forced to come to some sort of decision and we don’t waste time in endless meetings and committees. Team retrospectives are a good example. During a standard retrospective every member of the team lists the issues that they consider important, the team then votes on all the issues to make sure the more important ones are discussed first (another example of prioritization). Why do we need to vote? Because, the retrospective is timeboxed, we only have X minutes and we’ll only be able to get through so many things. The problem here, is that often the same issues crop up every time, but are never voted up to the top and so are never discussed. Does that mean the problem is less pressing – possibly? Does it mean the problem doesn’t exist – not by a long shot?

If nothing gets done about an issue for long enough, people stop bringing it up. Why bother, it never gets discussed anyway, it’s more efficient to just drop it. Now you have a problem in stealth mode that can grow and develop in all sorts of unexpected ways. Such as becoming an ingrained part of the culture (_I’ve looked at aspects of culture before, it is an extremely diverse topic and I am planning to touch on it in several upcoming posts_). People get used to it, and it takes on an element of tradition. Have you ever tried to change a tradition? It doesn’t matter if it’s helpful or detrimental, once the team has fully internalized it – good luck trying to budge it. And all this as a result of timeboxing and prioritization applied blindly – practices that are benign and helpful most of the time – causing a lot of harm.

You always need to adapt and adjust according to the situation; this is why we have people running projects and not machines. If a discussion seems to be leading somewhere good, don’t worry about the timeboxing let it run, only cut it short if it stagnates. Retrospectives are the same, I do believe it is well worth spending as much time as necessary to go through all the problems the team is facing. It is a small price to pay for not allowing issues to fester. Keep an eye on what is bugging your team about the code. Prioritizing an unimportant feature higher can often deal with these issues cleanly and efficiently. It is not all about the business value, or rather, there is more to business value than just financial impact. The general health of the development team has intrinsic business value all of its own.

Images by Michael Valiant and hockadilly