views:

44

answers:

2

I've got a class that serializes data. I may want to serialize this data as JSON, or perhaps YAML. Can I cleanly swap YAML for JSON objects in this case? I was hoping I could do something like the following. Is it a pipe dream?

FORMATS = {
  :json => JSON,
  :yaml => YAML,
}

def serialize(data, format)
  FORMATS[format].serialize(data)
end
A: 

If JSON and YAML are classes or modules that already exist, you can write:

FORMATS = { :json => "JSON", :yaml => "YAML" }

def serialize(data, format)
    Kernel.const_get(FORMATS[format]).serialize(data) # 'serialize' is a class method in this case
end
floatless
Actually, you don't need to convert classes to and from string, the example OP has posted should work just fine, as classes are objects in Ruby.
Mladen Jablanović
It's true, but I thought class names are strings in the provided example. My fault.
floatless
+2  A: 

The code you have written should work just fine, provided that classes JSON and YAML both have class method called serialize. But I think the method that actually exists is #dump.

So, you would have:

require 'json'
require 'yaml'

FORMATS = {
  :json => JSON,
  :yaml => YAML,
}

def serialize(data, format)
  FORMATS[format].dump(data)
end

hash = {:a => 2}
puts serialize hash, :json
#=> {"a":2}

puts serialize hash, :yaml
#=> --- 
#=> :a: 2
Mladen Jablanović
Sweet. So they already have a common interface to serializing. Now, how about deserializing?
Blaine LaFreniere
Oh, durr hurr, it's `parse`. Nevermind!
Blaine LaFreniere
Thank you for confirming my suspicions good sir.
Blaine LaFreniere