Using the double-splat operator in Ruby

The double-splat operator is one of my favorite additions in Ruby 2.0. For some reason, the two little asterisks together make me happier than an optional Hash parameter in a method. Even so, outside of method definitions, I didn’t realize there was a use for the double-splat operator until I dug into a bug in Hashie. I liked the result enough that I wanted to take a quick minute and share what I found.

If you write any modern JavaScript, you might have seen the following pattern:

function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return {
        ...state,
        visibilityFilter: action.filter
      };
    default:
      return state;
  }
}

That ... spread operator is really nice for creating new objects from others without modifying the originals. I really liked this when I built my first Redux-based JavaScript application because it removes a lot of the ceremony around Object.assign.

Sometimes you don’t yet have enough information to create an object. When that happens Hash is a great proxy for an object until you understand your domain a little better. I wanted the same behavior in Ruby for building up Hashes in these cases. For a while, I relied on Hash#merge, but then I saw this bug on Hashie.

Double-splat operator

To solve this problem, you can use the double-splat operator in a different way. Check out the following code:

def todo_app(state = initial_state, action)
  case action.type
  when SET_VISIBILITY_FILTER then { **state, visibility_filter: action.filter }
  else state
  end
end

This snippet works exactly the same way as the JavaScript version! I think that’s a really elegant answer to my original question.

Interestingly, if you compile down the instruction sequence for this code, you will see that it uses the C version of Hash#merge under the covers. I like that I’m getting the semantics of state.merge(visibility_filter: action.filter), but can express it in a way that my JavaScript-writing friends can easily understand.

If there’s one way to do something in Ruby, there’s probably at least one more. I think this is one of the reasons many people like Ruby: they can express their thoughts in the manner that is easiest for them.

That’s all I have for you today. Did you know about the double-splat operator in this case?