This week (or, rather, last week) I finished Refactoring: Ruby Edition by Jay Fields and performed some more refactorings on Redmine. I discovered that the second half of the book had more value than the first and that even good code can be improved significantly.

Refactoring: Ruby Edition

After reading the first half of the book, I stated that the book didn't provide too much value beyond Fowler's original. After reading the second half, I would disagree with that assessment. The catalog continually introduced several alternative ways to do something in Ruby that you wouldn't be able to do in Java (the language of the original book).

These alternative methods are actually very powerful when put into practice. After playing with the refactorings, I believe that they give a Ruby developer better tools to refactor and could, possibly, give the Ruby developer the power to create better abstractions that allow for better code.

Some of my favorite refactorings given in the catalog include those that use the Ruby block syntax. For example, the following code

def total
    result = 0
    items.each do |item|
        result += item.value

can be refactored into

def total
    items.inject(0) { |sum, item| sum + item.value }

and I absolutely love that. As long as you know what inject means (and, while that's a bad name, there doesn't seem to be a better one), this code makes perfect sense, is shorter and very DRY. I like all three of those. In Java, to do this you would need to create a convoluted anonymous class that wouldn't necessarily improve the code.

I would recommend this book to any developer that is writing serious Ruby code, perhaps even experienced ruby developers. While experienced developers may be familiar with the Rubyisms, this book describes a methodical, structured way to introduce those Rubyisms during refactoring. For people new to Ruby, this is a must; and, for people that practice TDD, this book should be attached to your hip.

Refactoring Redmine, Part 3

This was my last encounter with Redmine and I came away happy with my work. While Redmine has some very good, solid code throughout, there were always areas that could be refactored. This particular area was a very small class file that likely was never revisited after it was written.

Step 1

Extract Methods

Step 2

Introduce Guard

Step 3

Extract Methods

Step 4

Introduce Guard

Step 5

Rename methods

Step 6

Extract Methods

Step 7

Introduce Default Parameter

Step 8

Step 9

Rename Method

Step 10

Decomposing if block to guard clauses. I think that this is a great refactor for the arrow head anti-pattern. Quick and easy to get rid of.

Step 11

Extract Conditional To Method

Step 12

Consolidating Conditional. I think that this is a really cool, effective refactor. It is obviously a mix of Extract(/Inline) Method and Consolidate(/Break Up) Conditional, but its effectiveness is more than the sum.

Step 13

Rename Method

Analysis of Redmine Refactor

I felt that this was by far my best refactor to date. The code that I refactored was not terrible. I could read the code without much struggle. However, because I applied the refactoring tool, I think that the code turned out orders of magnitude better. I could now quickly glance over the code and understand what was going on.