Sundered Peak

through the mind of kyle tolle

Refactoring a Ruby Case Statement to a Hash

What follows is a refactoring I discovered recently and have found useful. Recording it here so that I can refer to it in the future and perhaps others will find it helpful. The example is simplified, but I hope it serves the purpose of illustration.

The Setup

I have processing I need to do based on some input. The value of the input determines which class I’m going to use to process it. In this example, I need to chew some fruit based on a code given to me.

The Case Statement Way

The way I’ve done it before was to use a case statement to determine the type of the fruit I need. After that, I can chew that particular kind of fruit. If I didn’t get a code, I don’t chew anything.

def eat(fruit_code)
  fruit_type =
    case fruit_code
     when 'a'
       Apple
     when 'b'
      Banana
     when 'c'
      Coconut
     when 'o'
      Orange
    end

  fruit_type.new.chew if fruit_type
end

The Hash Way

But I’ve discovered there’s a more succinct way to do this using a hash instead.

FRUIT_TYPES=
  { 'a' => Apple, 'b' => Banana, 'c' => Coconut, 'o' => Orange }.
    freeze

def eat(fruit_code)
  fruit_type = FRUIT_TYPES[fruit_code]

  fruit_type.new.chew if fruit_type
end

I like this refactoring because it allows me to condense several lines of code into one or a few. And it’s apparent, we’re looking up the fruit’s class.

Notes

This works when the interface on the classes is the same. The case statement only determines the class type and the processing is the same after that.

I’ve continued to use the case statement way when the number of arguments for initializing each class varies, since it didn’t seem apparent how I could do that in the hash.

Conclusion

Does this seem like something you’d find helpful? Are there other means of accomplishing this goal that I haven’t considered? I’ve love to hear to hear any feedback.