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.