2013-03-17 14 views
9

Come serializzare un array e deserializzare di nuovo da una stringa? Ho provato il seguente codice, ma in realtà non restituisce l'array originale di interi ma fa l'array di stringhe.Come serializzare un array e deserializzare indietro

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' ] 

C'è un modo per farlo tornare a numeri interi senza avere la .collect{ |x| x.to_i }?

risposta

29

Il modo standard è con Marshal:

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

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

Ma si può anche farlo con JSON:

require 'json' 

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

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

O YAML:

require 'yaml' 

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

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

Spalato è solo uno strumento per tagliare le stringhe - non sa da dove viene quella stringa.

Esistono molti modi per serializzare i dati: YAML, JSON e Marshal sono tre che fanno parte della Ruby Standard Library. Tutti distinguono tra stringhe, numeri interi e così via.

Ci sono pro e contro per ciascuno. Ad esempio, caricare i dati di Marshal da una fonte non attendibile è pericoloso e Marshal non è adatto se è necessario scambiare i dati con codice non Ruby. JSON è solitamente un buon tuttofare.

+1

Cosa c'è di pericoloso nel caricamento dei dati marshallati? Stai forse pensando a "eval"? Marshal è l'unico modo per garantire la codifica originale. – pguardiario

+2

Per citare i documenti ruby ​​per il maresciallo "Per impostazione, il carico può deserializzare quasi tutte le classi caricate nel processo Ruby. In molti casi ciò può portare all'esecuzione di codice remoto se i dati Marshal vengono caricati da una fonte non attendibile." –

+1

Mi chiedo se è possibile fornire un esempio specifico in cui, nel caso dell'OP, ciò potrebbe accadere. Non penso sia davvero possibile. – pguardiario

Problemi correlati