This bit of helper code came up in a Semaphore code review:
It’s written in an unnecessarily imperative style. The first thing that irked me is that it’s setting up an empty array and returning it at the end. You can avoid that by using Object#tap like this:
Tap is an implementation of the K combinator in Ruby. It yields the receiver to a block and returns it when the block returns. We use the block to add elements to the empty array and when the block returns it yields the mutated array.
Since we have two cases, mutating the array seems unnecessary:
- For every branch we return an array pair of branch name and url
- There are no branches and we just return an array with a pair “No Branches” and an empty string for the url
We can write this method in a more declarative way:
Map is a higher order function that applies a function to every element of an enumerable, in this case an array, and returns a new array with the values the function evaluates to.
This method also relies on the @projects variable. If it’s not there or if it’s named differently, the helper becomes useless. The last part of the refactoring is parametrizing the helper:
While I’m sure someone could code-golf it some more, the idea is to make methods and helpers more declarative, closer to what you would write in Haskell or Clojure. I should mention that the above helper function is not pure since we’re using url helpers and they could change if we change our route structure.
But this is close enough for a Rails view helper.