11

How do I serialize an array and deserialize it back from a string? I tried the following code, but it doesn't really return the original array of integers but does for the array of strings.

 x = [1,2,3].join(',') # maybe this is not the correct way to serialize to string?
 => '1,2,3'

 x = x.split(',')
 => [ '1', '2', '3' ]

Is there a way to get it back to integers without having the .collect{ |x| x.to_i }?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Kokizzu
  • 24,974
  • 37
  • 137
  • 233

2 Answers2

33

The standard way is with Marshal:

x = Marshal.dump([1, 2, 3])
#=> "\x04\b[\bi\x06i\ai\b"

Marshal.load(x)
#=> [1, 2, 3]

But you can also do it with JSON:

require 'json'

x = [1, 2, 3].to_json
#=> "[1,2,3]"

JSON::parse(x)
#=> [1, 2, 3]

Or YAML:

require 'yaml'

x = [1, 2, 3].to_yaml
#=> "---\n- 1\n- 2\n- 3\n"

YAML.load(x)
#=> [1, 2, 3]
Guilherme Bernal
  • 8,183
  • 25
  • 43
3

Split is just a tool for chopping up strings - it doesn't know where that string came from.

There are many ways of serialising data: YAML, JSON and Marshal being three that are part of the Ruby Standard Library. All distinguish between strings, integers and so on.

There are pros and cons for each. For example, loading Marshal data from an untrusted source is dangerous and Marshal isn't good if you need to exchange the data with non-Ruby code. JSON is usually a good allrounder.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • 1
    What's dangerous about loading marshalled data? Are you maybe thinking about `eval`? Marshal is the only way to ensure the original encoding. – pguardiario Mar 17 '13 at 13:15
  • 2
    To quote the ruby docs for marshal "By design, ::load can deserialize almost any class loaded into the Ruby process. In many cases this can lead to remote code execution if the Marshal data is loaded from an untrusted source." – Frederick Cheung Mar 17 '13 at 14:43
  • 1
    I'm wondering if you can give a specific example where in OP's case that might happen though. I don't think it's really possible. – pguardiario Mar 17 '13 at 14:53
  • 2
    If you control the source data you're fine. If not ... http://tenderlovemaking.com/2013/02/06/yaml-f7u12.html is about YAML but equally applicable to marshal – Frederick Cheung Mar 17 '13 at 17:24