I’s on #rubyonrails the other day when someone asked: how do I tidy this up?

  1. def Creation.make(raw, content_type)
  2. if Movie::MIME_TYPES.include?(content_type)
  3. Movie.new(raw)
  4. elsif Music::MIME_TYPES.include?(content_type)
  5. Music.new(raw)
  6. elsif Picture::MIME_TYPES.include?(content_type)
  7. Picture.new(raw)
  8. elsif Fiction::MIME_TYPES.include?(content_type)
  9. Fiction.new(raw)
  10. else
  11. Creation.new(raw)
  12. end
  13. end

This problem intrigued me and I knew there had to be a cleaner way to do it – I think if yo have that many if’s on the same thing (in this case MIME)TYPES.includ?(content_type) then it can always cleaner…

I came up with:

  1. types={:png =>"Picture",:gif=>"Picture", :jpg =>"Picture", :mp3 =>"Sound"}
  2. object_of_desired_class=ObjectSpace.const_get(types["png".to_param]).new

However, if you read the comments, you’ll see there is a better solution, which is the following (kindly provided by Emmanuel Oga):

  1. types= {:png => Picture, :gif=> Picture, :jpg => Picture, :mp3 => Sound}
  2. desired= "png"
  3. object_of_desired_class= types[desired.intern].new

“because a hash can store ANY object, even classes (as you may already know, in ruby classes are also objects :) ” – Emmanuel Oga

Many thanks to Emmanuel for correcting my code! That is exactly what this blog is for, for sharing and perfecting, so please if you read any of the articles, and see better ways of doing things, please feel free to post!