I’s on #rubyonrails the other day when someone asked: how do I tidy this up?
- def Creation.make(raw, content_type)
- if Movie::MIME_TYPES.include?(content_type)
- Movie.new(raw)
- elsif Music::MIME_TYPES.include?(content_type)
- Music.new(raw)
- elsif Picture::MIME_TYPES.include?(content_type)
- Picture.new(raw)
- elsif Fiction::MIME_TYPES.include?(content_type)
- Fiction.new(raw)
- else
- Creation.new(raw)
- end
- 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:
- types={:png =>"Picture",:gif=>"Picture", :jpg =>"Picture", :mp3 =>"Sound"}
- 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):
- types= {:png => Picture, :gif=> Picture, :jpg => Picture, :mp3 => Sound}
- desired= "png"
- 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!

RSS Feed
ObjectSpace is not the nicest thing to play in ruby… it seems very expensive to do that. Why not:
types= {:png => Picture, :gif=> Picture, :jpg => Picture, :mp3 => Sound} desired= “png” 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 :)
Or, if you prefer:
types={:png =>”Picture”,:gif=>”Picture”, :jpg =>”Picture”, :mp3 =>”Sound”} object_of_desired_class= eval(types[“png”.to_param]).new
althought eval could be a little slow. Here eval(“Picture”) becomes object Picture, which can be a class.