2

I'm consuming a web-service and using Savon to do +-1000 (paid) requests and parse the requests to a csv file. I save the xml.hash response in a file if the parsing failed. How can I initialize an hash that was saved to a file? (or should I save in XML and then let savon make it into a hash it again?

Extra info:

client = Savon.client do
    wsdl "url"
end

response = client.call(:read_request) do 
  message "dat:number" => number 
end

I use the response.hash to build/parse my csv data. Ex:

name = response.hash[:description][:name]

If the building failed I'm thinking about saving the response.hash to a file. But the problem is I don't know how to reuse the saved response (XML/Hash) so that an updated version of the building/parsing can be run using the saved response.

Jeff
  • 1,871
  • 1
  • 17
  • 28
  • 1
    You're going to have to provide some sample data and/or some sample code. Nobody here is telepathic. – tadman Jul 11 '14 at 16:56
  • I added extra explanation. It comes down to this: I want to save the value of a variable to a file so I can recover that variable later on for reuse. – Jeff Jul 11 '14 at 17:07
  • Post some code and say what doesn't work. Be as specific as possible. – Some Guy Jul 11 '14 at 17:22
  • possible duplicate of [How can I save an object to a file?](http://stackoverflow.com/questions/4310217/how-can-i-save-an-object-to-a-file) – Andrew Jul 11 '14 at 20:25

2 Answers2

3

You want to serialize the Hash to a file then deserialize it back again.

You can do it in text with YAML or JSON and in a binary via Marshal.

Marshal

def serialize_marshal filepath, object
  File.open( filepath, "wb" ) {|f| Marshal.dump object, f }
end

def deserialize_marshal filepath
  File.open( filepath, "rb") {|f| Marshal.load(f)}
end

Marshaled data has a major and minor version number written with it, so it's not guaranteed to always load in another Ruby if the Marshal data version changes.

YAML

require 'yaml'

def serialize_yaml filepath, object
  File.open( filepath, "w" ) {|f| YAML.dump object, f }
end

def deserialize_yaml filepath
  File.open( filepath, "r") {|f| YAML.load(f) }
end

JSON

require 'json'

def serialize_json filepath, object
  File.open( filepath, "w" ) {|f| JSON.dump object, f }
end

def deserialize_json filepath
  File.open( filepath, "r") {|f| JSON.load(f)}
end

Anecdotally, YAML is slow, Marshal and JSON are quick.

Matt
  • 68,711
  • 7
  • 155
  • 158
1

If your code is expecting to use/manipulate a ruby hash as demonstrated above, then if you want to save the Savon response, then use the json gem and do something like:

require 'json'

File.open("responseX.json","w") do |f| 
  f << response.hash.to_json 
end

Then if you need to read that file to recreate your response hash:

File.open('responseX.json').each do |line|
  reponseHash = JSON.parse(line)
  # do something with responseHash
end
jshort
  • 1,006
  • 8
  • 23